]> git.hungrycats.org Git - linux/commitdiff
Btrfs: add missing inode item update in fallocate()
authorFilipe Manana <fdmanana@suse.com>
Tue, 14 Jul 2015 13:06:47 +0000 (14:06 +0100)
committerZygo Blaxell <zblaxell@thirteen.furryterror.org>
Thu, 16 Jul 2015 23:41:23 +0000 (19:41 -0400)
(bnc#938023).

suse-commit: 4f61a739e2bef56c25f9a883afff48bffcd47515
(cherry picked from commit dfe466f4e9ea672ee944c0493bdb0659afd2da7d)

fs/btrfs/file.c

index 30982bbd31c30c2b154836b0f51b94c37e22923c..f3c96d6ac601bfcfb2a584351236d9e5c4628fb3 100644 (file)
@@ -2673,23 +2673,34 @@ static long btrfs_fallocate(struct file *file, int mode,
                                                        1 << inode->i_blkbits,
                                                        offset + len,
                                                        &alloc_hint);
-
-                       if (ret < 0) {
-                               free_extent_map(em);
-                               break;
-                       }
                } else if (actual_end > inode->i_size &&
                           !(mode & FALLOC_FL_KEEP_SIZE)) {
+                       struct btrfs_trans_handle *trans;
+
                        /*
                         * We didn't need to allocate any more space, but we
                         * still extended the size of the file so we need to
-                        * update i_size.
+                        * update i_size and the inode item.
                         */
-                       inode->i_ctime = CURRENT_TIME;
-                       i_size_write(inode, actual_end);
-                       btrfs_ordered_update_i_size(inode, actual_end, NULL);
+                       trans = btrfs_start_transaction(root, 1);
+                       if (IS_ERR(trans)) {
+                               ret = PTR_ERR(trans);
+                       } else {
+                               inode->i_ctime = CURRENT_TIME;
+                               i_size_write(inode, actual_end);
+                               btrfs_ordered_update_i_size(inode, actual_end,
+                                                           NULL);
+                               ret = btrfs_update_inode(trans, root, inode);
+                               if (ret)
+                                       btrfs_end_transaction(trans, root);
+                               else
+                                       ret = btrfs_end_transaction(trans,
+                                                                   root);
+                       }
                }
                free_extent_map(em);
+               if (ret < 0)
+                       break;
 
                cur_offset = last_byte;
                if (cur_offset >= alloc_end) {