0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/fs.h>
0009 #include <linux/stat.h>
0010 #include <linux/slab.h>
0011 #include <linux/namei.h>
0012 #include "cifsfs.h"
0013 #include "cifspdu.h"
0014 #include "cifsglob.h"
0015 #include "cifsproto.h"
0016 #include "cifs_debug.h"
0017 #include "cifs_fs_sb.h"
0018 #include "cifs_unicode.h"
0019 #include "smb2proto.h"
0020 #include "cifs_ioctl.h"
0021
0022
0023
0024
0025
0026 #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1)
0027 #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1))
0028 #define CIFS_MF_SYMLINK_LINK_OFFSET (CIFS_MF_SYMLINK_MD5_OFFSET+(32+1))
0029 #define CIFS_MF_SYMLINK_LINK_MAXLEN (1024)
0030 #define CIFS_MF_SYMLINK_FILE_SIZE \
0031 (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN)
0032
0033 #define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n"
0034 #define CIFS_MF_SYMLINK_MD5_FORMAT "%16phN\n"
0035 #define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) md5_hash
0036
0037 static int
0038 symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
0039 {
0040 int rc;
0041 struct crypto_shash *md5 = NULL;
0042 struct sdesc *sdescmd5 = NULL;
0043
0044 rc = cifs_alloc_hash("md5", &md5, &sdescmd5);
0045 if (rc)
0046 goto symlink_hash_err;
0047
0048 rc = crypto_shash_init(&sdescmd5->shash);
0049 if (rc) {
0050 cifs_dbg(VFS, "%s: Could not init md5 shash\n", __func__);
0051 goto symlink_hash_err;
0052 }
0053 rc = crypto_shash_update(&sdescmd5->shash, link_str, link_len);
0054 if (rc) {
0055 cifs_dbg(VFS, "%s: Could not update with link_str\n", __func__);
0056 goto symlink_hash_err;
0057 }
0058 rc = crypto_shash_final(&sdescmd5->shash, md5_hash);
0059 if (rc)
0060 cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
0061
0062 symlink_hash_err:
0063 cifs_free_hash(&md5, &sdescmd5);
0064 return rc;
0065 }
0066
0067 static int
0068 parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len,
0069 char **_link_str)
0070 {
0071 int rc;
0072 unsigned int link_len;
0073 const char *md5_str1;
0074 const char *link_str;
0075 u8 md5_hash[16];
0076 char md5_str2[34];
0077
0078 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
0079 return -EINVAL;
0080
0081 md5_str1 = (const char *)&buf[CIFS_MF_SYMLINK_MD5_OFFSET];
0082 link_str = (const char *)&buf[CIFS_MF_SYMLINK_LINK_OFFSET];
0083
0084 rc = sscanf(buf, CIFS_MF_SYMLINK_LEN_FORMAT, &link_len);
0085 if (rc != 1)
0086 return -EINVAL;
0087
0088 if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
0089 return -EINVAL;
0090
0091 rc = symlink_hash(link_len, link_str, md5_hash);
0092 if (rc) {
0093 cifs_dbg(FYI, "%s: MD5 hash failure: %d\n", __func__, rc);
0094 return rc;
0095 }
0096
0097 scnprintf(md5_str2, sizeof(md5_str2),
0098 CIFS_MF_SYMLINK_MD5_FORMAT,
0099 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
0100
0101 if (strncmp(md5_str1, md5_str2, 17) != 0)
0102 return -EINVAL;
0103
0104 if (_link_str) {
0105 *_link_str = kstrndup(link_str, link_len, GFP_KERNEL);
0106 if (!*_link_str)
0107 return -ENOMEM;
0108 }
0109
0110 *_link_len = link_len;
0111 return 0;
0112 }
0113
0114 static int
0115 format_mf_symlink(u8 *buf, unsigned int buf_len, const char *link_str)
0116 {
0117 int rc;
0118 unsigned int link_len;
0119 unsigned int ofs;
0120 u8 md5_hash[16];
0121
0122 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
0123 return -EINVAL;
0124
0125 link_len = strlen(link_str);
0126
0127 if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
0128 return -ENAMETOOLONG;
0129
0130 rc = symlink_hash(link_len, link_str, md5_hash);
0131 if (rc) {
0132 cifs_dbg(FYI, "%s: MD5 hash failure: %d\n", __func__, rc);
0133 return rc;
0134 }
0135
0136 scnprintf(buf, buf_len,
0137 CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT,
0138 link_len,
0139 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
0140
0141 ofs = CIFS_MF_SYMLINK_LINK_OFFSET;
0142 memcpy(buf + ofs, link_str, link_len);
0143
0144 ofs += link_len;
0145 if (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
0146 buf[ofs] = '\n';
0147 ofs++;
0148 }
0149
0150 while (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
0151 buf[ofs] = ' ';
0152 ofs++;
0153 }
0154
0155 return 0;
0156 }
0157
0158 bool
0159 couldbe_mf_symlink(const struct cifs_fattr *fattr)
0160 {
0161 if (!S_ISREG(fattr->cf_mode))
0162
0163 return false;
0164
0165 if (fattr->cf_eof != CIFS_MF_SYMLINK_FILE_SIZE)
0166
0167 return false;
0168
0169 return true;
0170 }
0171
0172 static int
0173 create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon,
0174 struct cifs_sb_info *cifs_sb, const char *fromName,
0175 const char *toName)
0176 {
0177 int rc;
0178 u8 *buf;
0179 unsigned int bytes_written = 0;
0180
0181 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
0182 if (!buf)
0183 return -ENOMEM;
0184
0185 rc = format_mf_symlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName);
0186 if (rc)
0187 goto out;
0188
0189 if (tcon->ses->server->ops->create_mf_symlink)
0190 rc = tcon->ses->server->ops->create_mf_symlink(xid, tcon,
0191 cifs_sb, fromName, buf, &bytes_written);
0192 else
0193 rc = -EOPNOTSUPP;
0194
0195 if (rc)
0196 goto out;
0197
0198 if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE)
0199 rc = -EIO;
0200 out:
0201 kfree(buf);
0202 return rc;
0203 }
0204
0205 static int
0206 query_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon,
0207 struct cifs_sb_info *cifs_sb, const unsigned char *path,
0208 char **symlinkinfo)
0209 {
0210 int rc;
0211 u8 *buf = NULL;
0212 unsigned int link_len = 0;
0213 unsigned int bytes_read = 0;
0214
0215 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
0216 if (!buf)
0217 return -ENOMEM;
0218
0219 if (tcon->ses->server->ops->query_mf_symlink)
0220 rc = tcon->ses->server->ops->query_mf_symlink(xid, tcon,
0221 cifs_sb, path, buf, &bytes_read);
0222 else
0223 rc = -ENOSYS;
0224
0225 if (rc)
0226 goto out;
0227
0228 if (bytes_read == 0) {
0229 rc = -EINVAL;
0230 goto out;
0231 }
0232
0233 rc = parse_mf_symlink(buf, bytes_read, &link_len, symlinkinfo);
0234 out:
0235 kfree(buf);
0236 return rc;
0237 }
0238
0239 int
0240 check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
0241 struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
0242 const unsigned char *path)
0243 {
0244 int rc;
0245 u8 *buf = NULL;
0246 unsigned int link_len = 0;
0247 unsigned int bytes_read = 0;
0248
0249 if (!couldbe_mf_symlink(fattr))
0250
0251 return 0;
0252
0253 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
0254 if (!buf)
0255 return -ENOMEM;
0256
0257 if (tcon->ses->server->ops->query_mf_symlink)
0258 rc = tcon->ses->server->ops->query_mf_symlink(xid, tcon,
0259 cifs_sb, path, buf, &bytes_read);
0260 else
0261 rc = -ENOSYS;
0262
0263 if (rc)
0264 goto out;
0265
0266 if (bytes_read == 0)
0267 goto out;
0268
0269 rc = parse_mf_symlink(buf, bytes_read, &link_len, NULL);
0270 if (rc == -EINVAL) {
0271
0272 rc = 0;
0273 goto out;
0274 }
0275
0276 if (rc != 0)
0277 goto out;
0278
0279
0280 fattr->cf_eof = link_len;
0281 fattr->cf_mode &= ~S_IFMT;
0282 fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
0283 fattr->cf_dtype = DT_LNK;
0284 out:
0285 kfree(buf);
0286 return rc;
0287 }
0288
0289 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
0290
0291
0292
0293
0294 int
0295 cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
0296 struct cifs_sb_info *cifs_sb, const unsigned char *path,
0297 char *pbuf, unsigned int *pbytes_read)
0298 {
0299 int rc;
0300 int oplock = 0;
0301 struct cifs_fid fid;
0302 struct cifs_open_parms oparms;
0303 struct cifs_io_parms io_parms = {0};
0304 int buf_type = CIFS_NO_BUFFER;
0305 FILE_ALL_INFO file_info;
0306
0307 oparms.tcon = tcon;
0308 oparms.cifs_sb = cifs_sb;
0309 oparms.desired_access = GENERIC_READ;
0310 oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
0311 oparms.disposition = FILE_OPEN;
0312 oparms.path = path;
0313 oparms.fid = &fid;
0314 oparms.reconnect = false;
0315
0316 rc = CIFS_open(xid, &oparms, &oplock, &file_info);
0317 if (rc)
0318 return rc;
0319
0320 if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
0321 rc = -ENOENT;
0322
0323 goto out;
0324 }
0325
0326 io_parms.netfid = fid.netfid;
0327 io_parms.pid = current->tgid;
0328 io_parms.tcon = tcon;
0329 io_parms.offset = 0;
0330 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
0331
0332 rc = CIFSSMBRead(xid, &io_parms, pbytes_read, &pbuf, &buf_type);
0333 out:
0334 CIFSSMBClose(xid, tcon, fid.netfid);
0335 return rc;
0336 }
0337
0338 int
0339 cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
0340 struct cifs_sb_info *cifs_sb, const unsigned char *path,
0341 char *pbuf, unsigned int *pbytes_written)
0342 {
0343 int rc;
0344 int oplock = 0;
0345 struct cifs_fid fid;
0346 struct cifs_open_parms oparms;
0347 struct cifs_io_parms io_parms = {0};
0348
0349 oparms.tcon = tcon;
0350 oparms.cifs_sb = cifs_sb;
0351 oparms.desired_access = GENERIC_WRITE;
0352 oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
0353 oparms.disposition = FILE_CREATE;
0354 oparms.path = path;
0355 oparms.fid = &fid;
0356 oparms.reconnect = false;
0357
0358 rc = CIFS_open(xid, &oparms, &oplock, NULL);
0359 if (rc)
0360 return rc;
0361
0362 io_parms.netfid = fid.netfid;
0363 io_parms.pid = current->tgid;
0364 io_parms.tcon = tcon;
0365 io_parms.offset = 0;
0366 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
0367
0368 rc = CIFSSMBWrite(xid, &io_parms, pbytes_written, pbuf);
0369 CIFSSMBClose(xid, tcon, fid.netfid);
0370 return rc;
0371 }
0372 #endif
0373
0374
0375
0376
0377 int
0378 smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
0379 struct cifs_sb_info *cifs_sb, const unsigned char *path,
0380 char *pbuf, unsigned int *pbytes_read)
0381 {
0382 int rc;
0383 struct cifs_fid fid;
0384 struct cifs_open_parms oparms;
0385 struct cifs_io_parms io_parms = {0};
0386 int buf_type = CIFS_NO_BUFFER;
0387 __le16 *utf16_path;
0388 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
0389 struct smb2_file_all_info *pfile_info = NULL;
0390
0391 oparms.tcon = tcon;
0392 oparms.cifs_sb = cifs_sb;
0393 oparms.desired_access = GENERIC_READ;
0394 oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
0395 oparms.disposition = FILE_OPEN;
0396 oparms.fid = &fid;
0397 oparms.reconnect = false;
0398
0399 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
0400 if (utf16_path == NULL)
0401 return -ENOMEM;
0402
0403 pfile_info = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
0404 GFP_KERNEL);
0405
0406 if (pfile_info == NULL) {
0407 kfree(utf16_path);
0408 return -ENOMEM;
0409 }
0410
0411 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, pfile_info, NULL,
0412 NULL, NULL);
0413 if (rc)
0414 goto qmf_out_open_fail;
0415
0416 if (pfile_info->EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
0417
0418 rc = -ENOENT;
0419 goto qmf_out;
0420 }
0421
0422 io_parms.netfid = fid.netfid;
0423 io_parms.pid = current->tgid;
0424 io_parms.tcon = tcon;
0425 io_parms.offset = 0;
0426 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
0427 io_parms.persistent_fid = fid.persistent_fid;
0428 io_parms.volatile_fid = fid.volatile_fid;
0429 rc = SMB2_read(xid, &io_parms, pbytes_read, &pbuf, &buf_type);
0430 qmf_out:
0431 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
0432 qmf_out_open_fail:
0433 kfree(utf16_path);
0434 kfree(pfile_info);
0435 return rc;
0436 }
0437
0438 int
0439 smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
0440 struct cifs_sb_info *cifs_sb, const unsigned char *path,
0441 char *pbuf, unsigned int *pbytes_written)
0442 {
0443 int rc;
0444 struct cifs_fid fid;
0445 struct cifs_open_parms oparms;
0446 struct cifs_io_parms io_parms = {0};
0447 __le16 *utf16_path;
0448 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
0449 struct kvec iov[2];
0450
0451 cifs_dbg(FYI, "%s: path: %s\n", __func__, path);
0452
0453 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
0454 if (!utf16_path)
0455 return -ENOMEM;
0456
0457 oparms.tcon = tcon;
0458 oparms.cifs_sb = cifs_sb;
0459 oparms.desired_access = GENERIC_WRITE;
0460 oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
0461 oparms.disposition = FILE_CREATE;
0462 oparms.fid = &fid;
0463 oparms.reconnect = false;
0464
0465 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
0466 NULL, NULL);
0467 if (rc) {
0468 kfree(utf16_path);
0469 return rc;
0470 }
0471
0472 io_parms.netfid = fid.netfid;
0473 io_parms.pid = current->tgid;
0474 io_parms.tcon = tcon;
0475 io_parms.offset = 0;
0476 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
0477 io_parms.persistent_fid = fid.persistent_fid;
0478 io_parms.volatile_fid = fid.volatile_fid;
0479
0480
0481 iov[1].iov_base = pbuf;
0482 iov[1].iov_len = CIFS_MF_SYMLINK_FILE_SIZE;
0483
0484 rc = SMB2_write(xid, &io_parms, pbytes_written, iov, 1);
0485
0486
0487 if ((rc == 0) && (*pbytes_written != CIFS_MF_SYMLINK_FILE_SIZE))
0488 rc = -EIO;
0489
0490 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
0491
0492 kfree(utf16_path);
0493 return rc;
0494 }
0495
0496
0497
0498
0499
0500 int
0501 cifs_hardlink(struct dentry *old_file, struct inode *inode,
0502 struct dentry *direntry)
0503 {
0504 int rc = -EACCES;
0505 unsigned int xid;
0506 const char *from_name, *to_name;
0507 void *page1, *page2;
0508 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
0509 struct tcon_link *tlink;
0510 struct cifs_tcon *tcon;
0511 struct TCP_Server_Info *server;
0512 struct cifsInodeInfo *cifsInode;
0513
0514 if (unlikely(cifs_forced_shutdown(cifs_sb)))
0515 return -EIO;
0516
0517 tlink = cifs_sb_tlink(cifs_sb);
0518 if (IS_ERR(tlink))
0519 return PTR_ERR(tlink);
0520 tcon = tlink_tcon(tlink);
0521
0522 xid = get_xid();
0523 page1 = alloc_dentry_path();
0524 page2 = alloc_dentry_path();
0525
0526 from_name = build_path_from_dentry(old_file, page1);
0527 if (IS_ERR(from_name)) {
0528 rc = PTR_ERR(from_name);
0529 goto cifs_hl_exit;
0530 }
0531 to_name = build_path_from_dentry(direntry, page2);
0532 if (IS_ERR(to_name)) {
0533 rc = PTR_ERR(to_name);
0534 goto cifs_hl_exit;
0535 }
0536
0537 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
0538 if (tcon->unix_ext)
0539 rc = CIFSUnixCreateHardLink(xid, tcon, from_name, to_name,
0540 cifs_sb->local_nls,
0541 cifs_remap(cifs_sb));
0542 else {
0543 #else
0544 {
0545 #endif
0546 server = tcon->ses->server;
0547 if (!server->ops->create_hardlink) {
0548 rc = -ENOSYS;
0549 goto cifs_hl_exit;
0550 }
0551 rc = server->ops->create_hardlink(xid, tcon, from_name, to_name,
0552 cifs_sb);
0553 if ((rc == -EIO) || (rc == -EINVAL))
0554 rc = -EOPNOTSUPP;
0555 }
0556
0557 d_drop(direntry);
0558
0559
0560
0561
0562
0563 if (d_really_is_positive(old_file)) {
0564 cifsInode = CIFS_I(d_inode(old_file));
0565 if (rc == 0) {
0566 spin_lock(&d_inode(old_file)->i_lock);
0567 inc_nlink(d_inode(old_file));
0568 spin_unlock(&d_inode(old_file)->i_lock);
0569
0570
0571
0572
0573
0574
0575
0576 }
0577
0578
0579
0580
0581
0582
0583 cifsInode->time = 0;
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593 }
0594
0595 cifs_hl_exit:
0596 free_dentry_path(page1);
0597 free_dentry_path(page2);
0598 free_xid(xid);
0599 cifs_put_tlink(tlink);
0600 return rc;
0601 }
0602
0603 const char *
0604 cifs_get_link(struct dentry *direntry, struct inode *inode,
0605 struct delayed_call *done)
0606 {
0607 int rc = -ENOMEM;
0608 unsigned int xid;
0609 const char *full_path;
0610 void *page;
0611 char *target_path = NULL;
0612 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
0613 struct tcon_link *tlink = NULL;
0614 struct cifs_tcon *tcon;
0615 struct TCP_Server_Info *server;
0616
0617 if (!direntry)
0618 return ERR_PTR(-ECHILD);
0619
0620 xid = get_xid();
0621
0622 tlink = cifs_sb_tlink(cifs_sb);
0623 if (IS_ERR(tlink)) {
0624 free_xid(xid);
0625 return ERR_CAST(tlink);
0626 }
0627 tcon = tlink_tcon(tlink);
0628 server = tcon->ses->server;
0629
0630 page = alloc_dentry_path();
0631 full_path = build_path_from_dentry(direntry, page);
0632 if (IS_ERR(full_path)) {
0633 free_xid(xid);
0634 cifs_put_tlink(tlink);
0635 free_dentry_path(page);
0636 return ERR_CAST(full_path);
0637 }
0638
0639 cifs_dbg(FYI, "Full path: %s inode = 0x%p\n", full_path, inode);
0640
0641 rc = -EACCES;
0642
0643
0644
0645
0646 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
0647 rc = query_mf_symlink(xid, tcon, cifs_sb, full_path,
0648 &target_path);
0649
0650 if (rc != 0 && server->ops->query_symlink) {
0651 struct cifsInodeInfo *cifsi = CIFS_I(inode);
0652 bool reparse_point = false;
0653
0654 if (cifsi->cifsAttrs & ATTR_REPARSE)
0655 reparse_point = true;
0656
0657 rc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path,
0658 &target_path, reparse_point);
0659 }
0660
0661 free_dentry_path(page);
0662 free_xid(xid);
0663 cifs_put_tlink(tlink);
0664 if (rc != 0) {
0665 kfree(target_path);
0666 return ERR_PTR(rc);
0667 }
0668 set_delayed_call(done, kfree_link, target_path);
0669 return target_path;
0670 }
0671
0672 int
0673 cifs_symlink(struct user_namespace *mnt_userns, struct inode *inode,
0674 struct dentry *direntry, const char *symname)
0675 {
0676 int rc = -EOPNOTSUPP;
0677 unsigned int xid;
0678 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
0679 struct tcon_link *tlink;
0680 struct cifs_tcon *pTcon;
0681 const char *full_path;
0682 void *page;
0683 struct inode *newinode = NULL;
0684
0685 if (unlikely(cifs_forced_shutdown(cifs_sb)))
0686 return -EIO;
0687
0688 page = alloc_dentry_path();
0689 if (!page)
0690 return -ENOMEM;
0691
0692 xid = get_xid();
0693
0694 tlink = cifs_sb_tlink(cifs_sb);
0695 if (IS_ERR(tlink)) {
0696 rc = PTR_ERR(tlink);
0697 goto symlink_exit;
0698 }
0699 pTcon = tlink_tcon(tlink);
0700
0701 full_path = build_path_from_dentry(direntry, page);
0702 if (IS_ERR(full_path)) {
0703 rc = PTR_ERR(full_path);
0704 goto symlink_exit;
0705 }
0706
0707 cifs_dbg(FYI, "Full path: %s\n", full_path);
0708 cifs_dbg(FYI, "symname is %s\n", symname);
0709
0710
0711 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
0712 rc = create_mf_symlink(xid, pTcon, cifs_sb, full_path, symname);
0713 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
0714 else if (pTcon->unix_ext)
0715 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
0716 cifs_sb->local_nls,
0717 cifs_remap(cifs_sb));
0718 #endif
0719
0720
0721
0722
0723 if (rc == 0) {
0724 if (pTcon->posix_extensions)
0725 rc = smb311_posix_get_inode_info(&newinode, full_path, inode->i_sb, xid);
0726 else if (pTcon->unix_ext)
0727 rc = cifs_get_inode_info_unix(&newinode, full_path,
0728 inode->i_sb, xid);
0729 else
0730 rc = cifs_get_inode_info(&newinode, full_path, NULL,
0731 inode->i_sb, xid, NULL);
0732
0733 if (rc != 0) {
0734 cifs_dbg(FYI, "Create symlink ok, getinodeinfo fail rc = %d\n",
0735 rc);
0736 } else {
0737 d_instantiate(direntry, newinode);
0738 }
0739 }
0740 symlink_exit:
0741 free_dentry_path(page);
0742 cifs_put_tlink(tlink);
0743 free_xid(xid);
0744 return rc;
0745 }