diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-08-07 23:32:25 (GMT) |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-08-19 17:01:33 (GMT) |
commit | b067ba1f1b3fa7ec798d35e12aed6cdba9cea905 (patch) | |
tree | 1095778a55a4577811f6f98d0e1a21822bbf47ab /fs/f2fs/inline.c | |
parent | e1c42045203071c4634b89e696037357810d3083 (diff) | |
download | linux-b067ba1f1b3fa7ec798d35e12aed6cdba9cea905.tar.xz |
f2fs: should convert inline_data during the mkwrite
If mkwrite is called to an inode having inline_data, it can overwrite the data
index space as NEW_ADDR. (e.g., the first 4 bytes are coincidently zero)
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/inline.c')
-rw-r--r-- | fs/f2fs/inline.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 5beecce..1ec512d 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -124,9 +124,10 @@ out: return err; } -int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size) +int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size, + struct page *page) { - struct page *page; + struct page *new_page = page; int err; if (!f2fs_has_inline_data(inode)) @@ -134,17 +135,20 @@ int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size) else if (to_size <= MAX_INLINE_DATA) return 0; - page = grab_cache_page(inode->i_mapping, 0); - if (!page) - return -ENOMEM; + if (!page || page->index != 0) { + new_page = grab_cache_page(inode->i_mapping, 0); + if (!new_page) + return -ENOMEM; + } - err = __f2fs_convert_inline_data(inode, page); - f2fs_put_page(page, 1); + err = __f2fs_convert_inline_data(inode, new_page); + if (!page || page->index != 0) + f2fs_put_page(new_page, 1); return err; } int f2fs_write_inline_data(struct inode *inode, - struct page *page, unsigned size) + struct page *page, unsigned size) { void *src_addr, *dst_addr; struct page *ipage; |