From: Greg Kroah-Hartman Date: Wed, 18 Dec 2013 20:51:28 +0000 (-0800) Subject: 3.10-stable patches X-Git-Tag: v3.4.75~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b526a1f21189c74a8404ce431ea8c28cd6f7a719;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: btrfs-do-not-run-snapshot-aware-defragment-on-error.patch btrfs-fix-hole-check-in-log_one_extent.patch btrfs-fix-incorrect-inode-acl-reset.patch btrfs-fix-memory-leak-of-chunks-extent-map.patch --- diff --git a/queue-3.10/btrfs-do-not-run-snapshot-aware-defragment-on-error.patch b/queue-3.10/btrfs-do-not-run-snapshot-aware-defragment-on-error.patch new file mode 100644 index 00000000000..40a68b744f0 --- /dev/null +++ b/queue-3.10/btrfs-do-not-run-snapshot-aware-defragment-on-error.patch @@ -0,0 +1,131 @@ +From 6f519564d7d978c00351d9ab6abac3deeac31621 Mon Sep 17 00:00:00 2001 +From: Liu Bo +Date: Tue, 29 Oct 2013 10:45:05 +0800 +Subject: Btrfs: do not run snapshot-aware defragment on error + +From: Liu Bo + +commit 6f519564d7d978c00351d9ab6abac3deeac31621 upstream. + +If something wrong happens in write endio, running snapshot-aware defragment +can end up with undefined results, maybe a crash, so we should avoid it. + +In order to share similar code, this also adds a helper to free the struct for +snapshot-aware defrag. + +Signed-off-by: Liu Bo +Signed-off-by: Josef Bacik +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/inode.c | 47 ++++++++++++++++++++++++++++------------------- + 1 file changed, 28 insertions(+), 19 deletions(-) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -2419,10 +2419,23 @@ out_unlock: + return ret; + } + ++static void free_sa_defrag_extent(struct new_sa_defrag_extent *new) ++{ ++ struct old_sa_defrag_extent *old, *tmp; ++ ++ if (!new) ++ return; ++ ++ list_for_each_entry_safe(old, tmp, &new->head, list) { ++ list_del(&old->list); ++ kfree(old); ++ } ++ kfree(new); ++} ++ + static void relink_file_extents(struct new_sa_defrag_extent *new) + { + struct btrfs_path *path; +- struct old_sa_defrag_extent *old, *tmp; + struct sa_defrag_extent_backref *backref; + struct sa_defrag_extent_backref *prev = NULL; + struct inode *inode; +@@ -2465,16 +2478,11 @@ static void relink_file_extents(struct n + kfree(prev); + + btrfs_free_path(path); +- +- list_for_each_entry_safe(old, tmp, &new->head, list) { +- list_del(&old->list); +- kfree(old); +- } + out: ++ free_sa_defrag_extent(new); ++ + atomic_dec(&root->fs_info->defrag_running); + wake_up(&root->fs_info->transaction_wait); +- +- kfree(new); + } + + static struct new_sa_defrag_extent * +@@ -2484,7 +2492,7 @@ record_old_file_extents(struct inode *in + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_path *path; + struct btrfs_key key; +- struct old_sa_defrag_extent *old, *tmp; ++ struct old_sa_defrag_extent *old; + struct new_sa_defrag_extent *new; + int ret; + +@@ -2532,7 +2540,7 @@ record_old_file_extents(struct inode *in + if (slot >= btrfs_header_nritems(l)) { + ret = btrfs_next_leaf(root, path); + if (ret < 0) +- goto out_free_list; ++ goto out_free_path; + else if (ret > 0) + break; + continue; +@@ -2561,7 +2569,7 @@ record_old_file_extents(struct inode *in + + old = kmalloc(sizeof(*old), GFP_NOFS); + if (!old) +- goto out_free_list; ++ goto out_free_path; + + offset = max(new->file_pos, key.offset); + end = min(new->file_pos + new->len, key.offset + num_bytes); +@@ -2583,15 +2591,10 @@ next: + + return new; + +-out_free_list: +- list_for_each_entry_safe(old, tmp, &new->head, list) { +- list_del(&old->list); +- kfree(old); +- } + out_free_path: + btrfs_free_path(path); + out_kfree: +- kfree(new); ++ free_sa_defrag_extent(new); + return NULL; + } + +@@ -2743,8 +2746,14 @@ out: + btrfs_remove_ordered_extent(inode, ordered_extent); + + /* for snapshot-aware defrag */ +- if (new) +- relink_file_extents(new); ++ if (new) { ++ if (ret) { ++ free_sa_defrag_extent(new); ++ atomic_dec(&root->fs_info->defrag_running); ++ } else { ++ relink_file_extents(new); ++ } ++ } + + /* once for us */ + btrfs_put_ordered_extent(ordered_extent); diff --git a/queue-3.10/btrfs-fix-hole-check-in-log_one_extent.patch b/queue-3.10/btrfs-fix-hole-check-in-log_one_extent.patch new file mode 100644 index 00000000000..da7def1c297 --- /dev/null +++ b/queue-3.10/btrfs-fix-hole-check-in-log_one_extent.patch @@ -0,0 +1,34 @@ +From ed9e8af88e2551aaa6bf51d8063a2493e2d71597 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Mon, 14 Oct 2013 17:23:08 -0400 +Subject: Btrfs: fix hole check in log_one_extent + +From: Josef Bacik + +commit ed9e8af88e2551aaa6bf51d8063a2493e2d71597 upstream. + +I added an assert to make sure we were looking up aligned offsets for csums and +I tripped it when running xfstests. This is because log_one_extent was checking +if block_start == 0 for a hole instead of EXTENT_MAP_HOLE. This worked out fine +in practice it seems, but it adds a lot of extra work that is uneeded. With +this fix I'm no longer tripping my assert. Thanks, + +Signed-off-by: Josef Bacik +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/tree-log.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -3314,7 +3314,7 @@ static int log_one_extent(struct btrfs_t + btrfs_set_token_file_extent_type(leaf, fi, + BTRFS_FILE_EXTENT_REG, + &token); +- if (em->block_start == 0) ++ if (em->block_start == EXTENT_MAP_HOLE) + skip_csum = true; + } + diff --git a/queue-3.10/btrfs-fix-incorrect-inode-acl-reset.patch b/queue-3.10/btrfs-fix-incorrect-inode-acl-reset.patch new file mode 100644 index 00000000000..e6f9dae5da6 --- /dev/null +++ b/queue-3.10/btrfs-fix-incorrect-inode-acl-reset.patch @@ -0,0 +1,72 @@ +From 8185554d3eb09d23a805456b6fa98dcbb34aa518 Mon Sep 17 00:00:00 2001 +From: Filipe David Borba Manana +Date: Tue, 15 Oct 2013 18:44:00 +0100 +Subject: Btrfs: fix incorrect inode acl reset + +From: Filipe David Borba Manana + +commit 8185554d3eb09d23a805456b6fa98dcbb34aa518 upstream. + +When a directory has a default ACL and a subdirectory is created +under that directory, btrfs_init_acl() is called when the +subdirectory's inode is created to initialize the inode's ACL +(inherited from the parent directory) but it was clearing the ACL +from the inode after setting it if posix_acl_create() returned +success, instead of clearing it only if it returned an error. + +To reproduce this issue: + +$ mkfs.btrfs -f /dev/loop0 +$ mount /dev/loop0 /mnt +$ mkdir /mnt/acl +$ setfacl -d --set u::rwx,g::rwx,o::- /mnt/acl +$ getfacl /mnt/acl +user::rwx +group::rwx +other::r-x +default:user::rwx +default:group::rwx +default:other::--- + +$ mkdir /mnt/acl/dir1 +$ getfacl /mnt/acl/dir1 +user::rwx +group::rwx +other::--- + +After unmounting and mounting again the filesystem, fgetacl returned the +expected ACL: + +$ umount /mnt/acl +$ mount /dev/loop0 /mnt +$ getfacl /mnt/acl/dir1 +user::rwx +group::rwx +other::--- +default:user::rwx +default:group::rwx +default:other::--- + +Meaning that the underlying xattr was persisted. + +Reported-by: Giuseppe Fierro +Signed-off-by: Filipe David Borba Manana +Signed-off-by: Josef Bacik +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/acl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/btrfs/acl.c ++++ b/fs/btrfs/acl.c +@@ -229,7 +229,7 @@ int btrfs_init_acl(struct btrfs_trans_ha + if (ret > 0) { + /* we need an acl */ + ret = btrfs_set_acl(trans, inode, acl, ACL_TYPE_ACCESS); +- } else { ++ } else if (ret < 0) { + cache_no_acl(inode); + } + } else { diff --git a/queue-3.10/btrfs-fix-memory-leak-of-chunks-extent-map.patch b/queue-3.10/btrfs-fix-memory-leak-of-chunks-extent-map.patch new file mode 100644 index 00000000000..e3fd811d6a2 --- /dev/null +++ b/queue-3.10/btrfs-fix-memory-leak-of-chunks-extent-map.patch @@ -0,0 +1,39 @@ +From 7d3d1744f8a7d62e4875bd69cc2192a939813880 Mon Sep 17 00:00:00 2001 +From: Liu Bo +Date: Sun, 29 Sep 2013 10:33:16 +0800 +Subject: Btrfs: fix memory leak of chunks' extent map + +From: Liu Bo + +commit 7d3d1744f8a7d62e4875bd69cc2192a939813880 upstream. + +As we're hold a ref on looking up the extent map, we need to drop the ref +before returning to callers. + +Signed-off-by: Liu Bo +Signed-off-by: Josef Bacik +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/volumes.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -4248,6 +4248,7 @@ int btrfs_num_copies(struct btrfs_fs_inf + btrfs_emerg(fs_info, "Invalid mapping for %Lu-%Lu, got " + "%Lu-%Lu\n", logical, logical+len, em->start, + em->start + em->len); ++ free_extent_map(em); + return 1; + } + +@@ -4429,6 +4430,7 @@ static int __btrfs_map_block(struct btrf + btrfs_crit(fs_info, "found a bad mapping, wanted %Lu, " + "found %Lu-%Lu\n", logical, em->start, + em->start + em->len); ++ free_extent_map(em); + return -EINVAL; + } + diff --git a/queue-3.10/series b/queue-3.10/series index 759696fb2c8..5b706f61744 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -72,3 +72,7 @@ sc1200_wdt-fix-oops.patch nfsv4-wait-on-recovery-for-async-session-errors.patch ip6tnl-fix-use-after-free-of-fb_tnl_dev.patch revert-net-update-consumers-of-msg_more-to-recognize-msg_sendpage_notlast.patch +btrfs-fix-memory-leak-of-chunks-extent-map.patch +btrfs-fix-hole-check-in-log_one_extent.patch +btrfs-fix-incorrect-inode-acl-reset.patch +btrfs-do-not-run-snapshot-aware-defragment-on-error.patch