diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2013-08-14 11:25:21 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2013-09-08 15:27:34 -0400 |
commit | b42bf88828cde60772dc08201d0a4f1a0663d7bc (patch) | |
tree | 3b019e905c83aba6578b56ae5a49669f59db23cf /fs/cifs/link.c | |
parent | 3ae35cde67c1ec50267bcc55d81f4953b5f637c2 (diff) |
CIFS: Implement follow_link for SMB2
that allows to access files through symlink created on a server.
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/link.c')
-rw-r--r-- | fs/cifs/link.c | 24 |
1 files changed, 5 insertions, 19 deletions
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 562044f700e5..7e36ceba0c7a 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -509,6 +509,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | |||
509 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 509 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
510 | struct tcon_link *tlink = NULL; | 510 | struct tcon_link *tlink = NULL; |
511 | struct cifs_tcon *tcon; | 511 | struct cifs_tcon *tcon; |
512 | struct TCP_Server_Info *server; | ||
512 | 513 | ||
513 | xid = get_xid(); | 514 | xid = get_xid(); |
514 | 515 | ||
@@ -519,25 +520,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | |||
519 | goto out; | 520 | goto out; |
520 | } | 521 | } |
521 | tcon = tlink_tcon(tlink); | 522 | tcon = tlink_tcon(tlink); |
522 | 523 | server = tcon->ses->server; | |
523 | /* | ||
524 | * For now, we just handle symlinks with unix extensions enabled. | ||
525 | * Eventually we should handle NTFS reparse points, and MacOS | ||
526 | * symlink support. For instance... | ||
527 | * | ||
528 | * rc = CIFSSMBQueryReparseLinkInfo(...) | ||
529 | * | ||
530 | * For now, just return -EACCES when the server doesn't support posix | ||
531 | * extensions. Note that we still allow querying symlinks when posix | ||
532 | * extensions are manually disabled. We could disable these as well | ||
533 | * but there doesn't seem to be any harm in allowing the client to | ||
534 | * read them. | ||
535 | */ | ||
536 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) && | ||
537 | !cap_unix(tcon->ses)) { | ||
538 | rc = -EACCES; | ||
539 | goto out; | ||
540 | } | ||
541 | 524 | ||
542 | full_path = build_path_from_dentry(direntry); | 525 | full_path = build_path_from_dentry(direntry); |
543 | if (!full_path) | 526 | if (!full_path) |
@@ -559,6 +542,9 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | |||
559 | if ((rc != 0) && cap_unix(tcon->ses)) | 542 | if ((rc != 0) && cap_unix(tcon->ses)) |
560 | rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path, | 543 | rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path, |
561 | cifs_sb->local_nls); | 544 | cifs_sb->local_nls); |
545 | else if (rc != 0 && server->ops->query_symlink) | ||
546 | rc = server->ops->query_symlink(xid, tcon, full_path, | ||
547 | &target_path, cifs_sb); | ||
562 | 548 | ||
563 | kfree(full_path); | 549 | kfree(full_path); |
564 | out: | 550 | out: |