]> Pileus Git - ~andy/linux/blobdiff - fs/f2fs/file.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[~andy/linux] / fs / f2fs / file.c
index cf835e05f39b8dad9e3ecad4c03161bda42d5d55..0dfcef53a6ed830e442f8c174ea166b0d1b2eabd 100644 (file)
@@ -33,7 +33,6 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
        struct page *page = vmf->page;
        struct inode *inode = file_inode(vma->vm_file);
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
-       block_t old_blk_addr;
        struct dnode_of_data dn;
        int err;
 
@@ -44,30 +43,16 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
        /* block allocation */
        f2fs_lock_op(sbi);
        set_new_dnode(&dn, inode, NULL, NULL, 0);
-       err = get_dnode_of_data(&dn, page->index, ALLOC_NODE);
-       if (err) {
-               f2fs_unlock_op(sbi);
-               goto out;
-       }
-
-       old_blk_addr = dn.data_blkaddr;
-
-       if (old_blk_addr == NULL_ADDR) {
-               err = reserve_new_block(&dn);
-               if (err) {
-                       f2fs_put_dnode(&dn);
-                       f2fs_unlock_op(sbi);
-                       goto out;
-               }
-       }
-       f2fs_put_dnode(&dn);
+       err = f2fs_reserve_block(&dn, page->index);
        f2fs_unlock_op(sbi);
+       if (err)
+               goto out;
 
        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;
@@ -130,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);
@@ -217,7 +202,7 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count)
        raw_node = F2FS_NODE(dn->node_page);
        addr = blkaddr_in_node(raw_node) + ofs;
 
-       for ( ; count > 0; count--, addr++, dn->ofs_in_node++) {
+       for (; count > 0; count--, addr++, dn->ofs_in_node++) {
                block_t blkaddr = le32_to_cpu(*addr);
                if (blkaddr == NULL_ADDR)
                        continue;
@@ -256,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;
        }
@@ -266,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) {
@@ -308,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);
 
@@ -382,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));
@@ -460,12 +452,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;
 
@@ -500,12 +496,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;
 }
 
@@ -522,6 +512,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;
 
@@ -533,22 +527,10 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
 
                f2fs_lock_op(sbi);
                set_new_dnode(&dn, inode, NULL, NULL, 0);
-               ret = get_dnode_of_data(&dn, index, ALLOC_NODE);
-               if (ret) {
-                       f2fs_unlock_op(sbi);
-                       break;
-               }
-
-               if (dn.data_blkaddr == NULL_ADDR) {
-                       ret = reserve_new_block(&dn);
-                       if (ret) {
-                               f2fs_put_dnode(&dn);
-                               f2fs_unlock_op(sbi);
-                               break;
-                       }
-               }
-               f2fs_put_dnode(&dn);
+               ret = f2fs_reserve_block(&dn, index);
                f2fs_unlock_op(sbi);
+               if (ret)
+                       break;
 
                if (pg_start == pg_end)
                        new_size = offset + len;
@@ -579,7 +561,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);