Merge tag 'for-f2fs-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs updates from Jaegeuk Kim: "This patch-set includes the following major enhancement patches: - remount_fs callback function - restore parent inode number to enhance the fsync performance - xattr security labels - reduce the number of redundant lock/unlock data pages - avoid frequent write_inode calls The other minor bug fixes are as follows. - endian conversion bugs - various bugs in the roll-forward recovery routine" * tag 'for-f2fs-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (56 commits) f2fs: fix to recover i_size from roll-forward f2fs: remove the unused argument "sbi" of func destroy_fsync_dnodes() f2fs: remove reusing any prefree segments f2fs: code cleanup and simplify in func {find/add}_gc_inode f2fs: optimize the init_dirty_segmap function f2fs: fix an endian conversion bug detected by sparse f2fs: fix crc endian conversion f2fs: add remount_fs callback support f2fs: recover wrong pino after checkpoint during fsync f2fs: optimize do_write_data_page() f2fs: make locate_dirty_segment() as static f2fs: remove unnecessary parameter "offset" from __add_sum_entry() f2fs: avoid freqeunt write_inode calls f2fs: optimise the truncate_data_blocks_range() range f2fs: use the F2FS specific flags in f2fs_ioctl() f2fs: sync dir->i_size with its block allocation f2fs: fix i_blocks translation on various types of files f2fs: set sb->s_fs_info before calling parse_options() f2fs: support xattr security labels f2fs: fix iget/iput of dir during recovery ...
This commit is contained in:
@@ -68,7 +68,9 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs,
|
||||
struct buffer_head *bh_result)
|
||||
{
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
#ifdef CONFIG_F2FS_STAT_FS
|
||||
struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
|
||||
#endif
|
||||
pgoff_t start_fofs, end_fofs;
|
||||
block_t start_blkaddr;
|
||||
|
||||
@@ -78,7 +80,9 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_F2FS_STAT_FS
|
||||
sbi->total_hit_ext++;
|
||||
#endif
|
||||
start_fofs = fi->ext.fofs;
|
||||
end_fofs = fi->ext.fofs + fi->ext.len - 1;
|
||||
start_blkaddr = fi->ext.blk_addr;
|
||||
@@ -96,7 +100,9 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs,
|
||||
else
|
||||
bh_result->b_size = UINT_MAX;
|
||||
|
||||
#ifdef CONFIG_F2FS_STAT_FS
|
||||
sbi->read_hit_ext++;
|
||||
#endif
|
||||
read_unlock(&fi->ext.ext_lock);
|
||||
return 1;
|
||||
}
|
||||
@@ -199,7 +205,7 @@ struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync)
|
||||
if (dn.data_blkaddr == NEW_ADDR)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
page = grab_cache_page(mapping, index);
|
||||
page = grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
|
||||
if (!page)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@@ -233,19 +239,24 @@ struct page *get_lock_data_page(struct inode *inode, pgoff_t index)
|
||||
struct page *page;
|
||||
int err;
|
||||
|
||||
set_new_dnode(&dn, inode, NULL, NULL, 0);
|
||||
err = get_dnode_of_data(&dn, index, LOOKUP_NODE);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
f2fs_put_dnode(&dn);
|
||||
|
||||
if (dn.data_blkaddr == NULL_ADDR)
|
||||
return ERR_PTR(-ENOENT);
|
||||
repeat:
|
||||
page = grab_cache_page(mapping, index);
|
||||
page = grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
|
||||
if (!page)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
set_new_dnode(&dn, inode, NULL, NULL, 0);
|
||||
err = get_dnode_of_data(&dn, index, LOOKUP_NODE);
|
||||
if (err) {
|
||||
f2fs_put_page(page, 1);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
f2fs_put_dnode(&dn);
|
||||
|
||||
if (dn.data_blkaddr == NULL_ADDR) {
|
||||
f2fs_put_page(page, 1);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
if (PageUptodate(page))
|
||||
return page;
|
||||
|
||||
@@ -274,9 +285,10 @@ repeat:
|
||||
*
|
||||
* Also, caller should grab and release a mutex by calling mutex_lock_op() and
|
||||
* mutex_unlock_op().
|
||||
* Note that, npage is set only by make_empty_dir.
|
||||
*/
|
||||
struct page *get_new_data_page(struct inode *inode, pgoff_t index,
|
||||
bool new_i_size)
|
||||
struct page *get_new_data_page(struct inode *inode,
|
||||
struct page *npage, pgoff_t index, bool new_i_size)
|
||||
{
|
||||
struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
|
||||
struct address_space *mapping = inode->i_mapping;
|
||||
@@ -284,18 +296,20 @@ struct page *get_new_data_page(struct inode *inode, pgoff_t index,
|
||||
struct dnode_of_data dn;
|
||||
int err;
|
||||
|
||||
set_new_dnode(&dn, inode, NULL, NULL, 0);
|
||||
set_new_dnode(&dn, inode, npage, npage, 0);
|
||||
err = get_dnode_of_data(&dn, index, ALLOC_NODE);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
if (dn.data_blkaddr == NULL_ADDR) {
|
||||
if (reserve_new_block(&dn)) {
|
||||
f2fs_put_dnode(&dn);
|
||||
if (!npage)
|
||||
f2fs_put_dnode(&dn);
|
||||
return ERR_PTR(-ENOSPC);
|
||||
}
|
||||
}
|
||||
f2fs_put_dnode(&dn);
|
||||
if (!npage)
|
||||
f2fs_put_dnode(&dn);
|
||||
repeat:
|
||||
page = grab_cache_page(mapping, index);
|
||||
if (!page)
|
||||
@@ -325,6 +339,8 @@ repeat:
|
||||
if (new_i_size &&
|
||||
i_size_read(inode) < ((index + 1) << PAGE_CACHE_SHIFT)) {
|
||||
i_size_write(inode, ((index + 1) << PAGE_CACHE_SHIFT));
|
||||
/* Only the directory inode sets new_i_size */
|
||||
set_inode_flag(F2FS_I(inode), FI_UPDATE_DIR);
|
||||
mark_inode_dirty_sync(inode);
|
||||
}
|
||||
return page;
|
||||
@@ -481,8 +497,9 @@ int do_write_data_page(struct page *page)
|
||||
* If current allocation needs SSR,
|
||||
* it had better in-place writes for updated data.
|
||||
*/
|
||||
if (old_blk_addr != NEW_ADDR && !is_cold_data(page) &&
|
||||
need_inplace_update(inode)) {
|
||||
if (unlikely(old_blk_addr != NEW_ADDR &&
|
||||
!is_cold_data(page) &&
|
||||
need_inplace_update(inode))) {
|
||||
rewrite_data_page(F2FS_SB(inode->i_sb), page,
|
||||
old_blk_addr);
|
||||
} else {
|
||||
@@ -684,6 +701,27 @@ err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int f2fs_write_end(struct file *file,
|
||||
struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned copied,
|
||||
struct page *page, void *fsdata)
|
||||
{
|
||||
struct inode *inode = page->mapping->host;
|
||||
|
||||
SetPageUptodate(page);
|
||||
set_page_dirty(page);
|
||||
|
||||
if (pos + copied > i_size_read(inode)) {
|
||||
i_size_write(inode, pos + copied);
|
||||
mark_inode_dirty(inode);
|
||||
update_inode_page(inode);
|
||||
}
|
||||
|
||||
unlock_page(page);
|
||||
page_cache_release(page);
|
||||
return copied;
|
||||
}
|
||||
|
||||
static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb,
|
||||
const struct iovec *iov, loff_t offset, unsigned long nr_segs)
|
||||
{
|
||||
@@ -741,7 +779,7 @@ const struct address_space_operations f2fs_dblock_aops = {
|
||||
.writepage = f2fs_write_data_page,
|
||||
.writepages = f2fs_write_data_pages,
|
||||
.write_begin = f2fs_write_begin,
|
||||
.write_end = nobh_write_end,
|
||||
.write_end = f2fs_write_end,
|
||||
.set_page_dirty = f2fs_set_data_page_dirty,
|
||||
.invalidatepage = f2fs_invalidate_data_page,
|
||||
.releasepage = f2fs_release_data_page,
|
||||
|
Reference in New Issue
Block a user