diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-11 16:13:23 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-11 16:13:23 -0500 |
commit | 32fb378437a1d716e72a442237d7ead1f435ecf0 (patch) | |
tree | 411b25023d4df908fb8ca4517185d49c37c51e10 /fs/cifs | |
parent | 19ccb28e296d5afa299db1003d37e5d37994d46e (diff) | |
parent | fceef393a538134f03b778c5d2519e670269342f (diff) |
Merge branch 'work.symlinks' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs RCU symlink updates from Al Viro:
"Replacement of ->follow_link/->put_link, allowing to stay in RCU mode
even if the symlink is not an embedded one.
No changes since the mailbomb on Jan 1"
* 'work.symlinks' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
switch ->get_link() to delayed_call, kill ->put_link()
kill free_page_put_link()
teach nfs_get_link() to work in RCU mode
teach proc_self_get_link()/proc_thread_self_get_link() to work in RCU mode
teach shmem_get_link() to work in RCU mode
teach page_get_link() to work in RCU mode
replace ->follow_link() with new method that could stay in RCU mode
don't put symlink bodies in pagecache into highmem
namei: page_getlink() and page_follow_link_light() are the same thing
ufs: get rid of ->setattr() for symlinks
udf: don't duplicate page_symlink_inode_operations
logfs: don't duplicate page_symlink_inode_operations
switch befs long symlinks to page_symlink_operations
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifsfs.c | 3 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 5 | ||||
-rw-r--r-- | fs/cifs/link.c | 10 |
3 files changed, 10 insertions, 8 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index cbc0f4bca0c0..90e4e2b398b6 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -900,8 +900,7 @@ const struct inode_operations cifs_file_inode_ops = { | |||
900 | 900 | ||
901 | const struct inode_operations cifs_symlink_inode_ops = { | 901 | const struct inode_operations cifs_symlink_inode_ops = { |
902 | .readlink = generic_readlink, | 902 | .readlink = generic_readlink, |
903 | .follow_link = cifs_follow_link, | 903 | .get_link = cifs_get_link, |
904 | .put_link = kfree_put_link, | ||
905 | .permission = cifs_permission, | 904 | .permission = cifs_permission, |
906 | /* BB add the following two eventually */ | 905 | /* BB add the following two eventually */ |
907 | /* revalidate: cifs_revalidate, | 906 | /* revalidate: cifs_revalidate, |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index c3cc1609025f..26a1187d4323 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -120,9 +120,8 @@ extern struct vfsmount *cifs_dfs_d_automount(struct path *path); | |||
120 | #endif | 120 | #endif |
121 | 121 | ||
122 | /* Functions related to symlinks */ | 122 | /* Functions related to symlinks */ |
123 | extern const char *cifs_follow_link(struct dentry *direntry, void **cookie); | 123 | extern const char *cifs_get_link(struct dentry *, struct inode *, |
124 | extern int cifs_readlink(struct dentry *direntry, char __user *buffer, | 124 | struct delayed_call *); |
125 | int buflen); | ||
126 | extern int cifs_symlink(struct inode *inode, struct dentry *direntry, | 125 | extern int cifs_symlink(struct inode *inode, struct dentry *direntry, |
127 | const char *symname); | 126 | const char *symname); |
128 | extern int cifs_removexattr(struct dentry *, const char *); | 127 | extern int cifs_removexattr(struct dentry *, const char *); |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index e3548f73bdea..062c2375549a 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -627,9 +627,9 @@ cifs_hl_exit: | |||
627 | } | 627 | } |
628 | 628 | ||
629 | const char * | 629 | const char * |
630 | cifs_follow_link(struct dentry *direntry, void **cookie) | 630 | cifs_get_link(struct dentry *direntry, struct inode *inode, |
631 | struct delayed_call *done) | ||
631 | { | 632 | { |
632 | struct inode *inode = d_inode(direntry); | ||
633 | int rc = -ENOMEM; | 633 | int rc = -ENOMEM; |
634 | unsigned int xid; | 634 | unsigned int xid; |
635 | char *full_path = NULL; | 635 | char *full_path = NULL; |
@@ -639,6 +639,9 @@ cifs_follow_link(struct dentry *direntry, void **cookie) | |||
639 | struct cifs_tcon *tcon; | 639 | struct cifs_tcon *tcon; |
640 | struct TCP_Server_Info *server; | 640 | struct TCP_Server_Info *server; |
641 | 641 | ||
642 | if (!direntry) | ||
643 | return ERR_PTR(-ECHILD); | ||
644 | |||
642 | xid = get_xid(); | 645 | xid = get_xid(); |
643 | 646 | ||
644 | tlink = cifs_sb_tlink(cifs_sb); | 647 | tlink = cifs_sb_tlink(cifs_sb); |
@@ -678,7 +681,8 @@ cifs_follow_link(struct dentry *direntry, void **cookie) | |||
678 | kfree(target_path); | 681 | kfree(target_path); |
679 | return ERR_PTR(rc); | 682 | return ERR_PTR(rc); |
680 | } | 683 | } |
681 | return *cookie = target_path; | 684 | set_delayed_call(done, kfree_link, target_path); |
685 | return target_path; | ||
682 | } | 686 | } |
683 | 687 | ||
684 | int | 688 | int |