diff options
| author | Joel Becker <Joel.Becker@oracle.com> | 2009-04-06 19:43:42 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-05-09 10:49:40 -0400 |
| commit | a731d12d6ddd1e703770cacb5dfecb155b03ee06 (patch) | |
| tree | 601a1cef230bf0ad6c5969568f2ba3ef8a128333 | |
| parent | 265e771e8197cdb22a1e2556663173fb62c9cd91 (diff) | |
ocfs2: Use nd_set_link().
ocfs2 was hand-calling vfs_follow_link(), but there's no point to that.
Let's use page_follow_link_light() and nd_set_link().
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/ocfs2/symlink.c | 77 |
1 files changed, 37 insertions, 40 deletions
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c index ed0a0cfd68d2..579dd1b1110f 100644 --- a/fs/ocfs2/symlink.c +++ b/fs/ocfs2/symlink.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
| 40 | #include <linux/pagemap.h> | 40 | #include <linux/pagemap.h> |
| 41 | #include <linux/utsname.h> | 41 | #include <linux/utsname.h> |
| 42 | #include <linux/namei.h> | ||
| 42 | 43 | ||
| 43 | #define MLOG_MASK_PREFIX ML_NAMEI | 44 | #define MLOG_MASK_PREFIX ML_NAMEI |
| 44 | #include <cluster/masklog.h> | 45 | #include <cluster/masklog.h> |
| @@ -54,26 +55,6 @@ | |||
| 54 | 55 | ||
| 55 | #include "buffer_head_io.h" | 56 | #include "buffer_head_io.h" |
| 56 | 57 | ||
| 57 | static char *ocfs2_page_getlink(struct dentry * dentry, | ||
| 58 | struct page **ppage); | ||
| 59 | static char *ocfs2_fast_symlink_getlink(struct inode *inode, | ||
| 60 | struct buffer_head **bh); | ||
| 61 | |||
| 62 | /* get the link contents into pagecache */ | ||
| 63 | static char *ocfs2_page_getlink(struct dentry * dentry, | ||
| 64 | struct page **ppage) | ||
| 65 | { | ||
| 66 | struct page * page; | ||
| 67 | struct address_space *mapping = dentry->d_inode->i_mapping; | ||
| 68 | page = read_mapping_page(mapping, 0, NULL); | ||
| 69 | if (IS_ERR(page)) | ||
| 70 | goto sync_fail; | ||
| 71 | *ppage = page; | ||
| 72 | return kmap(page); | ||
| 73 | |||
| 74 | sync_fail: | ||
| 75 | return (char*)page; | ||
| 76 | } | ||
| 77 | 58 | ||
| 78 | static char *ocfs2_fast_symlink_getlink(struct inode *inode, | 59 | static char *ocfs2_fast_symlink_getlink(struct inode *inode, |
| 79 | struct buffer_head **bh) | 60 | struct buffer_head **bh) |
| @@ -128,40 +109,55 @@ out: | |||
| 128 | return ret; | 109 | return ret; |
| 129 | } | 110 | } |
| 130 | 111 | ||
| 131 | static void *ocfs2_follow_link(struct dentry *dentry, | 112 | static void *ocfs2_fast_follow_link(struct dentry *dentry, |
| 132 | struct nameidata *nd) | 113 | struct nameidata *nd) |
| 133 | { | 114 | { |
| 134 | int status; | 115 | int status = 0; |
| 135 | char *link; | 116 | int len; |
| 117 | char *target, *link = ERR_PTR(-ENOMEM); | ||
| 136 | struct inode *inode = dentry->d_inode; | 118 | struct inode *inode = dentry->d_inode; |
| 137 | struct page *page = NULL; | ||
| 138 | struct buffer_head *bh = NULL; | 119 | struct buffer_head *bh = NULL; |
| 139 | 120 | ||
| 140 | if (ocfs2_inode_is_fast_symlink(inode)) | 121 | mlog_entry_void(); |
| 141 | link = ocfs2_fast_symlink_getlink(inode, &bh); | 122 | |
| 142 | else | 123 | BUG_ON(!ocfs2_inode_is_fast_symlink(inode)); |
| 143 | link = ocfs2_page_getlink(dentry, &page); | 124 | target = ocfs2_fast_symlink_getlink(inode, &bh); |
| 144 | if (IS_ERR(link)) { | 125 | if (IS_ERR(target)) { |
| 145 | status = PTR_ERR(link); | 126 | status = PTR_ERR(target); |
| 146 | mlog_errno(status); | 127 | mlog_errno(status); |
| 147 | goto bail; | 128 | goto bail; |
| 148 | } | 129 | } |
| 149 | 130 | ||
| 150 | status = vfs_follow_link(nd, link); | 131 | /* Fast symlinks can't be large */ |
| 132 | len = strlen(target); | ||
| 133 | link = kzalloc(len + 1, GFP_NOFS); | ||
| 134 | if (!link) { | ||
| 135 | status = -ENOMEM; | ||
| 136 | mlog_errno(status); | ||
| 137 | goto bail; | ||
| 138 | } | ||
| 139 | |||
| 140 | memcpy(link, target, len); | ||
| 141 | nd_set_link(nd, link); | ||
| 151 | 142 | ||
| 152 | bail: | 143 | bail: |
| 153 | if (page) { | ||
| 154 | kunmap(page); | ||
| 155 | page_cache_release(page); | ||
| 156 | } | ||
| 157 | brelse(bh); | 144 | brelse(bh); |
| 158 | 145 | ||
| 159 | return ERR_PTR(status); | 146 | mlog_exit(status); |
| 147 | return status ? ERR_PTR(status) : link; | ||
| 148 | } | ||
| 149 | |||
| 150 | static void ocfs2_fast_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) | ||
| 151 | { | ||
| 152 | char *link = cookie; | ||
| 153 | |||
| 154 | kfree(link); | ||
| 160 | } | 155 | } |
| 161 | 156 | ||
| 162 | const struct inode_operations ocfs2_symlink_inode_operations = { | 157 | const struct inode_operations ocfs2_symlink_inode_operations = { |
| 163 | .readlink = page_readlink, | 158 | .readlink = page_readlink, |
| 164 | .follow_link = ocfs2_follow_link, | 159 | .follow_link = page_follow_link_light, |
| 160 | .put_link = page_put_link, | ||
| 165 | .getattr = ocfs2_getattr, | 161 | .getattr = ocfs2_getattr, |
| 166 | .setattr = ocfs2_setattr, | 162 | .setattr = ocfs2_setattr, |
| 167 | .setxattr = generic_setxattr, | 163 | .setxattr = generic_setxattr, |
| @@ -171,7 +167,8 @@ const struct inode_operations ocfs2_symlink_inode_operations = { | |||
| 171 | }; | 167 | }; |
| 172 | const struct inode_operations ocfs2_fast_symlink_inode_operations = { | 168 | const struct inode_operations ocfs2_fast_symlink_inode_operations = { |
| 173 | .readlink = ocfs2_readlink, | 169 | .readlink = ocfs2_readlink, |
| 174 | .follow_link = ocfs2_follow_link, | 170 | .follow_link = ocfs2_fast_follow_link, |
| 171 | .put_link = ocfs2_fast_put_link, | ||
| 175 | .getattr = ocfs2_getattr, | 172 | .getattr = ocfs2_getattr, |
| 176 | .setattr = ocfs2_setattr, | 173 | .setattr = ocfs2_setattr, |
| 177 | .setxattr = generic_setxattr, | 174 | .setxattr = generic_setxattr, |
