22 #include <linux/stat.h>
23 #include <linux/slab.h>
32 #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1)
33 #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1))
34 #define CIFS_MF_SYMLINK_LINK_OFFSET (CIFS_MF_SYMLINK_MD5_OFFSET+(32+1))
35 #define CIFS_MF_SYMLINK_LINK_MAXLEN (1024)
36 #define CIFS_MF_SYMLINK_FILE_SIZE \
37 (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN)
39 #define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n"
40 #define CIFS_MF_SYMLINK_MD5_FORMAT \
41 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n"
42 #define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) \
43 md5_hash[0], md5_hash[1], md5_hash[2], md5_hash[3], \
44 md5_hash[4], md5_hash[5], md5_hash[6], md5_hash[7], \
45 md5_hash[8], md5_hash[9], md5_hash[10], md5_hash[11],\
46 md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15]
49 symlink_hash(
unsigned int link_len,
const char *link_str,
u8 *md5_hash)
54 struct sdesc *sdescmd5;
59 cERROR(1,
"%s: Crypto md5 allocation error %d", __func__, rc);
62 size =
sizeof(
struct shash_desc) + crypto_shash_descsize(md5);
66 cERROR(1,
"%s: Memory allocation failure", __func__);
67 goto symlink_hash_err;
69 sdescmd5->shash.tfm = md5;
70 sdescmd5->shash.
flags = 0x0;
72 rc = crypto_shash_init(&sdescmd5->shash);
74 cERROR(1,
"%s: Could not init md5 shash", __func__);
75 goto symlink_hash_err;
79 cERROR(1,
"%s: Could not update iwth link_str", __func__);
80 goto symlink_hash_err;
84 cERROR(1,
"%s: Could not generate md5 hash", __func__);
87 crypto_free_shash(md5);
94 CIFSParseMFSymlink(
const u8 *
buf,
96 unsigned int *_link_len,
100 unsigned int link_len;
101 const char *md5_str1;
102 const char *link_str;
116 rc = symlink_hash(link_len, link_str, md5_hash);
118 cFYI(1,
"%s: MD5 hash failure: %d", __func__, rc);
122 snprintf(md5_str2,
sizeof(md5_str2),
126 if (
strncmp(md5_str1, md5_str2, 17) != 0)
135 *_link_len = link_len;
140 CIFSFormatMFSymlink(
u8 *buf,
unsigned int buf_len,
const char *link_str)
143 unsigned int link_len;
150 link_len =
strlen(link_str);
155 rc = symlink_hash(link_len, link_str, md5_hash);
157 cFYI(1,
"%s: MD5 hash failure: %d", __func__, rc);
167 memcpy(buf + ofs, link_str, link_len);
184 CIFSCreateMFSymLink(
const unsigned int xid,
struct cifs_tcon *tcon,
185 const char *fromName,
const char *toName,
194 unsigned int bytes_written = 0;
215 create_options, &netfid, &oplock,
NULL,
216 nls_codepage, remap);
222 io_parms.netfid = netfid;
224 io_parms.tcon = tcon;
241 CIFSQueryMFSymLink(
const unsigned int xid,
struct cifs_tcon *tcon,
242 const unsigned char *searchName,
char **symlinkinfo,
243 const struct nls_table *nls_codepage,
int remap)
250 unsigned int bytes_read = 0;
252 unsigned int link_len = 0;
254 FILE_ALL_INFO file_info;
258 nls_codepage, remap);
274 io_parms.tcon =
tcon;
278 rc =
CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
285 rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, symlinkinfo);
309 const unsigned char *
path,
320 unsigned int bytes_read = 0;
322 unsigned int link_len = 0;
323 FILE_ALL_INFO file_info;
331 return PTR_ERR(tlink);
332 pTcon = tlink_tcon(tlink);
356 io_parms.
tcon = pTcon;
360 rc =
CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
367 rc = CIFSParseMFSymlink(buf, bytes_read, &link_len,
NULL);
394 char *from_name =
NULL;
395 char *to_name =
NULL;
404 return PTR_ERR(tlink);
405 tcon = tlink_tcon(tlink);
411 if ((from_name ==
NULL) || (to_name ==
NULL)) {
422 server = tcon->
ses->server;
423 if (!server->
ops->create_hardlink)
425 rc = server->
ops->create_hardlink(xid, tcon, from_name, to_name,
438 cifsInode = CIFS_I(old_file->
d_inode);
440 spin_lock(&old_file->
d_inode->i_lock);
442 spin_unlock(&old_file->
d_inode->i_lock);
485 char *full_path =
NULL;
486 char *target_path =
NULL;
499 tcon = tlink_tcon(tlink);
515 !cap_unix(tcon->
ses)) {
524 cFYI(1,
"Full path: %s inode = 0x%p", full_path, inode);
532 rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path,
537 if ((rc != 0) && cap_unix(tcon->
ses))
545 target_path = ERR_PTR(rc);
551 nd_set_link(nd, target_path);
563 char *full_path =
NULL;
564 struct inode *newinode =
NULL;
573 pTcon = tlink_tcon(tlink);
576 if (full_path ==
NULL) {
581 cFYI(1,
"Full path: %s", full_path);
582 cFYI(1,
"symname is %s", symname);
586 rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
604 cFYI(1,
"Create symlink ok, getinodeinfo fail rc = %d",
619 char *
p = nd_get_link(nd);