diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-04-15 16:49:55 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-04-16 12:45:40 -0400 |
commit | feb7cbb079e63ebb7c0bd7022d2ba9c1dd15c69b (patch) | |
tree | 279b5dcd63730d042ef2cda231d115f703fa14e9 /fs/f2fs | |
parent | d0cae97cb600d84a7e00df6f83ab3b2f60d8d7f7 (diff) |
f2fs: avoid abnormal behavior on broken symlink
When f2fs_symlink was triggered and checkpoint was done before syncing its
link path, f2fs can get broken symlink like "xxx -> \0\0\0".
This incurs abnormal path_walk by VFS.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/namei.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 9f0eec4677fe..407dde3d7a92 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
15 | #include <linux/ctype.h> | 15 | #include <linux/ctype.h> |
16 | #include <linux/dcache.h> | 16 | #include <linux/dcache.h> |
17 | #include <linux/namei.h> | ||
17 | 18 | ||
18 | #include "f2fs.h" | 19 | #include "f2fs.h" |
19 | #include "node.h" | 20 | #include "node.h" |
@@ -295,6 +296,23 @@ fail: | |||
295 | return err; | 296 | return err; |
296 | } | 297 | } |
297 | 298 | ||
299 | static void *f2fs_follow_link(struct dentry *dentry, struct nameidata *nd) | ||
300 | { | ||
301 | struct page *page; | ||
302 | |||
303 | page = page_follow_link_light(dentry, nd); | ||
304 | if (IS_ERR(page)) | ||
305 | return page; | ||
306 | |||
307 | /* this is broken symlink case */ | ||
308 | if (*nd_get_link(nd) == 0) { | ||
309 | kunmap(page); | ||
310 | page_cache_release(page); | ||
311 | return ERR_PTR(-ENOENT); | ||
312 | } | ||
313 | return page; | ||
314 | } | ||
315 | |||
298 | static int f2fs_symlink(struct inode *dir, struct dentry *dentry, | 316 | static int f2fs_symlink(struct inode *dir, struct dentry *dentry, |
299 | const char *symname) | 317 | const char *symname) |
300 | { | 318 | { |
@@ -790,7 +808,7 @@ const struct inode_operations f2fs_dir_inode_operations = { | |||
790 | 808 | ||
791 | const struct inode_operations f2fs_symlink_inode_operations = { | 809 | const struct inode_operations f2fs_symlink_inode_operations = { |
792 | .readlink = generic_readlink, | 810 | .readlink = generic_readlink, |
793 | .follow_link = page_follow_link_light, | 811 | .follow_link = f2fs_follow_link, |
794 | .put_link = page_put_link, | 812 | .put_link = page_put_link, |
795 | .getattr = f2fs_getattr, | 813 | .getattr = f2fs_getattr, |
796 | .setattr = f2fs_setattr, | 814 | .setattr = f2fs_setattr, |