]> git.karo-electronics.de Git - linux-beck.git/blobdiff - fs/f2fs/file.c
f2fs: improve write performance under frequent fsync calls
[linux-beck.git] / fs / f2fs / file.c
index 1cd8e44b637f323ed4e60ee268730987d2e696ef..14511b00fffa1aa5760f9e3c7133b7a675a3a6c7 100644 (file)
@@ -50,9 +50,9 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
 
        file_update_time(vma->vm_file);
        lock_page(page);
-       if (page->mapping != inode->i_mapping ||
+       if (unlikely(page->mapping != inode->i_mapping ||
                        page_offset(page) > i_size_read(inode) ||
-                       !PageUptodate(page)) {
+                       !PageUptodate(page))) {
                unlock_page(page);
                err = -EFAULT;
                goto out;
@@ -115,12 +115,12 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        int ret = 0;
        bool need_cp = false;
        struct writeback_control wbc = {
-               .sync_mode = WB_SYNC_ALL,
+               .sync_mode = WB_SYNC_NONE,
                .nr_to_write = LONG_MAX,
                .for_reclaim = 0,
        };
 
-       if (f2fs_readonly(inode->i_sb))
+       if (unlikely(f2fs_readonly(inode->i_sb)))
                return 0;
 
        trace_f2fs_sync_file_enter(inode);
@@ -241,7 +241,7 @@ static void truncate_partial_data_page(struct inode *inode, u64 from)
                return;
 
        lock_page(page);
-       if (page->mapping != inode->i_mapping) {
+       if (unlikely(page->mapping != inode->i_mapping)) {
                f2fs_put_page(page, 1);
                return;
        }
@@ -251,21 +251,24 @@ static void truncate_partial_data_page(struct inode *inode, u64 from)
        f2fs_put_page(page, 1);
 }
 
-static int truncate_blocks(struct inode *inode, u64 from)
+int truncate_blocks(struct inode *inode, u64 from)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        unsigned int blocksize = inode->i_sb->s_blocksize;
        struct dnode_of_data dn;
        pgoff_t free_from;
-       int count = 0;
-       int err;
+       int count = 0, err = 0;
 
        trace_f2fs_truncate_blocks_enter(inode, from);
 
+       if (f2fs_has_inline_data(inode))
+               goto done;
+
        free_from = (pgoff_t)
                        ((from + blocksize - 1) >> (sbi->log_blocksize));
 
        f2fs_lock_op(sbi);
+
        set_new_dnode(&dn, inode, NULL, NULL, 0);
        err = get_dnode_of_data(&dn, free_from, LOOKUP_NODE);
        if (err) {
@@ -293,7 +296,7 @@ static int truncate_blocks(struct inode *inode, u64 from)
 free_next:
        err = truncate_inode_blocks(inode, free_from);
        f2fs_unlock_op(sbi);
-
+done:
        /* lastly zero out the first data page */
        truncate_partial_data_page(inode, from);
 
@@ -367,6 +370,10 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
 
        if ((attr->ia_valid & ATTR_SIZE) &&
                        attr->ia_size != i_size_read(inode)) {
+               err = f2fs_convert_inline_data(inode, attr->ia_size);
+               if (err)
+                       return err;
+
                truncate_setsize(inode, attr->ia_size);
                f2fs_truncate(inode);
                f2fs_balance_fs(F2FS_SB(inode->i_sb));
@@ -444,12 +451,16 @@ int truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end)
        return 0;
 }
 
-static int punch_hole(struct inode *inode, loff_t offset, loff_t len, int mode)
+static int punch_hole(struct inode *inode, loff_t offset, loff_t len)
 {
        pgoff_t pg_start, pg_end;
        loff_t off_start, off_end;
        int ret = 0;
 
+       ret = f2fs_convert_inline_data(inode, MAX_INLINE_DATA + 1);
+       if (ret)
+               return ret;
+
        pg_start = ((unsigned long long) offset) >> PAGE_CACHE_SHIFT;
        pg_end = ((unsigned long long) offset + len) >> PAGE_CACHE_SHIFT;
 
@@ -484,12 +495,6 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len, int mode)
                }
        }
 
-       if (!(mode & FALLOC_FL_KEEP_SIZE) &&
-               i_size_read(inode) <= (offset + len)) {
-               i_size_write(inode, offset);
-               mark_inode_dirty(inode);
-       }
-
        return ret;
 }
 
@@ -506,6 +511,10 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
        if (ret)
                return ret;
 
+       ret = f2fs_convert_inline_data(inode, offset + len);
+       if (ret)
+               return ret;
+
        pg_start = ((unsigned long long) offset) >> PAGE_CACHE_SHIFT;
        pg_end = ((unsigned long long) offset + len) >> PAGE_CACHE_SHIFT;
 
@@ -522,7 +531,6 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
                if (ret)
                        break;
 
-
                if (pg_start == pg_end)
                        new_size = offset + len;
                else if (index == pg_start && off_start)
@@ -552,7 +560,7 @@ static long f2fs_fallocate(struct file *file, int mode,
                return -EOPNOTSUPP;
 
        if (mode & FALLOC_FL_PUNCH_HOLE)
-               ret = punch_hole(inode, offset, len, mode);
+               ret = punch_hole(inode, offset, len);
        else
                ret = expand_inode_data(inode, offset, len, mode);