From: Greg Kroah-Hartman Date: Tue, 13 Mar 2018 14:19:28 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.14.27~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=acbf23549851fae42eaf56b47db0b852032a231b;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: ext4-inplace-xattr-block-update-fails-to-deduplicate-blocks.patch nfs-fix-an-incorrect-type-in-struct-nfs_direct_req.patch nfs-fix-unstable-write-completion.patch scsi-qla2xxx-replace-fcport-alloc-with-qla2x00_alloc_fcport.patch ubi-fix-race-condition-between-ubi-volume-creation-and-udev.patch --- diff --git a/queue-4.9/ext4-inplace-xattr-block-update-fails-to-deduplicate-blocks.patch b/queue-4.9/ext4-inplace-xattr-block-update-fails-to-deduplicate-blocks.patch new file mode 100644 index 00000000000..246207cf50c --- /dev/null +++ b/queue-4.9/ext4-inplace-xattr-block-update-fails-to-deduplicate-blocks.patch @@ -0,0 +1,64 @@ +From ec00022030da5761518476096626338bd67df57a Mon Sep 17 00:00:00 2001 +From: Tahsin Erdogan +Date: Sat, 5 Aug 2017 22:41:42 -0400 +Subject: ext4: inplace xattr block update fails to deduplicate blocks + +From: Tahsin Erdogan + +commit ec00022030da5761518476096626338bd67df57a upstream. + +When an xattr block has a single reference, block is updated inplace +and it is reinserted to the cache. Later, a cache lookup is performed +to see whether an existing block has the same contents. This cache +lookup will most of the time return the just inserted entry so +deduplication is not achieved. + +Running the following test script will produce two xattr blocks which +can be observed in "File ACL: " line of debugfs output: + + mke2fs -b 1024 -I 128 -F -O extent /dev/sdb 1G + mount /dev/sdb /mnt/sdb + + touch /mnt/sdb/{x,y} + + setfattr -n user.1 -v aaa /mnt/sdb/x + setfattr -n user.2 -v bbb /mnt/sdb/x + + setfattr -n user.1 -v aaa /mnt/sdb/y + setfattr -n user.2 -v bbb /mnt/sdb/y + + debugfs -R 'stat x' /dev/sdb | cat + debugfs -R 'stat y' /dev/sdb | cat + +This patch defers the reinsertion to the cache so that we can locate +other blocks with the same contents. + +Signed-off-by: Tahsin Erdogan +Signed-off-by: Theodore Ts'o +Reviewed-by: Andreas Dilger +Signed-off-by: Tommi Rantala +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/xattr.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -837,8 +837,6 @@ ext4_xattr_block_set(handle_t *handle, s + if (!IS_LAST_ENTRY(s->first)) + ext4_xattr_rehash(header(s->base), + s->here); +- ext4_xattr_cache_insert(ext4_mb_cache, +- bs->bh); + } + ext4_xattr_block_csum_set(inode, bs->bh); + unlock_buffer(bs->bh); +@@ -959,6 +957,7 @@ inserted: + } else if (bs->bh && s->base == bs->bh->b_data) { + /* We were modifying this block in-place. */ + ea_bdebug(bs->bh, "keeping this block"); ++ ext4_xattr_cache_insert(ext4_mb_cache, bs->bh); + new_bh = bs->bh; + get_bh(new_bh); + } else { diff --git a/queue-4.9/nfs-fix-an-incorrect-type-in-struct-nfs_direct_req.patch b/queue-4.9/nfs-fix-an-incorrect-type-in-struct-nfs_direct_req.patch new file mode 100644 index 00000000000..0a05861ba36 --- /dev/null +++ b/queue-4.9/nfs-fix-an-incorrect-type-in-struct-nfs_direct_req.patch @@ -0,0 +1,34 @@ +From d9ee65539d3eabd9ade46cca1780e3309ad0f907 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Tue, 6 Mar 2018 12:47:08 -0500 +Subject: NFS: Fix an incorrect type in struct nfs_direct_req + +From: Trond Myklebust + +commit d9ee65539d3eabd9ade46cca1780e3309ad0f907 upstream. + +The start offset needs to be of type loff_t. + +Fixed: 5fadeb47dcc5c ("nfs: count DIO good bytes correctly with mirroring") +Cc: stable@vger.kernel.org # v4.0+ +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/direct.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -86,10 +86,10 @@ struct nfs_direct_req { + struct nfs_direct_mirror mirrors[NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX]; + int mirror_count; + ++ loff_t io_start; /* Start offset for I/O */ + ssize_t count, /* bytes actually processed */ + max_count, /* max expected count */ + bytes_left, /* bytes left to be sent */ +- io_start, /* start of IO */ + error; /* any reported error */ + struct completion completion; /* wait for i/o completion */ + diff --git a/queue-4.9/nfs-fix-unstable-write-completion.patch b/queue-4.9/nfs-fix-unstable-write-completion.patch new file mode 100644 index 00000000000..da7fa8aa761 --- /dev/null +++ b/queue-4.9/nfs-fix-unstable-write-completion.patch @@ -0,0 +1,146 @@ +From c4f24df942a181699c5bab01b8e5e82b925f77f3 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Wed, 7 Mar 2018 15:22:31 -0500 +Subject: NFS: Fix unstable write completion + +From: Trond Myklebust + +commit c4f24df942a181699c5bab01b8e5e82b925f77f3 upstream. + +We do want to respect the FLUSH_SYNC argument to nfs_commit_inode() to +ensure that all outstanding COMMIT requests to the inode in question are +complete. Currently we may exit early from both nfs_commit_inode() and +nfs_write_inode() even if there are COMMIT requests in flight, or unstable +writes on the commit list. + +In order to get the right semantics w.r.t. sync_inode(), we don't need +to have nfs_commit_inode() reset the inode dirty flags when called from +nfs_wb_page() and/or nfs_wb_all(). We just need to ensure that +nfs_write_inode() leaves them in the right state if there are outstanding +commits, or stable pages. + +Reported-by: Scott Mayhew +Fixes: dc4fd9ab01ab ("nfs: don't wait on commit in nfs_commit_inode()...") +Cc: stable@vger.kernel.org # v4.14+ +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/write.c | 83 +++++++++++++++++++++++++++++---------------------------- + 1 file changed, 43 insertions(+), 40 deletions(-) + +--- a/fs/nfs/write.c ++++ b/fs/nfs/write.c +@@ -1847,40 +1847,43 @@ int nfs_generic_commit_list(struct inode + return status; + } + +-int nfs_commit_inode(struct inode *inode, int how) ++static int __nfs_commit_inode(struct inode *inode, int how, ++ struct writeback_control *wbc) + { + LIST_HEAD(head); + struct nfs_commit_info cinfo; + int may_wait = how & FLUSH_SYNC; +- int error = 0; +- int res; ++ int ret, nscan; + + nfs_init_cinfo_from_inode(&cinfo, inode); + nfs_commit_begin(cinfo.mds); +- res = nfs_scan_commit(inode, &head, &cinfo); +- if (res) +- error = nfs_generic_commit_list(inode, &head, how, &cinfo); ++ for (;;) { ++ ret = nscan = nfs_scan_commit(inode, &head, &cinfo); ++ if (ret <= 0) ++ break; ++ ret = nfs_generic_commit_list(inode, &head, how, &cinfo); ++ if (ret < 0) ++ break; ++ ret = 0; ++ if (wbc && wbc->sync_mode == WB_SYNC_NONE) { ++ if (nscan < wbc->nr_to_write) ++ wbc->nr_to_write -= nscan; ++ else ++ wbc->nr_to_write = 0; ++ } ++ if (nscan < INT_MAX) ++ break; ++ cond_resched(); ++ } + nfs_commit_end(cinfo.mds); +- if (res == 0) +- return res; +- if (error < 0) +- goto out_error; +- if (!may_wait) +- goto out_mark_dirty; +- error = wait_on_commit(cinfo.mds); +- if (error < 0) +- return error; +- return res; +-out_error: +- res = error; +- /* Note: If we exit without ensuring that the commit is complete, +- * we must mark the inode as dirty. Otherwise, future calls to +- * sync_inode() with the WB_SYNC_ALL flag set will fail to ensure +- * that the data is on the disk. +- */ +-out_mark_dirty: +- __mark_inode_dirty(inode, I_DIRTY_DATASYNC); +- return res; ++ if (ret || !may_wait) ++ return ret; ++ return wait_on_commit(cinfo.mds); ++} ++ ++int nfs_commit_inode(struct inode *inode, int how) ++{ ++ return __nfs_commit_inode(inode, how, NULL); + } + EXPORT_SYMBOL_GPL(nfs_commit_inode); + +@@ -1890,11 +1893,11 @@ int nfs_write_inode(struct inode *inode, + int flags = FLUSH_SYNC; + int ret = 0; + +- /* no commits means nothing needs to be done */ +- if (!nfsi->commit_info.ncommit) +- return ret; +- + if (wbc->sync_mode == WB_SYNC_NONE) { ++ /* no commits means nothing needs to be done */ ++ if (!nfsi->commit_info.ncommit) ++ goto check_requests_outstanding; ++ + /* Don't commit yet if this is a non-blocking flush and there + * are a lot of outstanding writes for this mapping. + */ +@@ -1905,16 +1908,16 @@ int nfs_write_inode(struct inode *inode, + flags = 0; + } + +- ret = nfs_commit_inode(inode, flags); +- if (ret >= 0) { +- if (wbc->sync_mode == WB_SYNC_NONE) { +- if (ret < wbc->nr_to_write) +- wbc->nr_to_write -= ret; +- else +- wbc->nr_to_write = 0; +- } +- return 0; +- } ++ ret = __nfs_commit_inode(inode, flags, wbc); ++ if (!ret) { ++ if (flags & FLUSH_SYNC) ++ return 0; ++ } else if (atomic_long_read(&nfsi->commit_info.ncommit)) ++ goto out_mark_dirty; ++ ++check_requests_outstanding: ++ if (!atomic_read(&nfsi->commit_info.rpcs_out)) ++ return ret; + out_mark_dirty: + __mark_inode_dirty(inode, I_DIRTY_DATASYNC); + return ret; diff --git a/queue-4.9/scsi-qla2xxx-replace-fcport-alloc-with-qla2x00_alloc_fcport.patch b/queue-4.9/scsi-qla2xxx-replace-fcport-alloc-with-qla2x00_alloc_fcport.patch new file mode 100644 index 00000000000..d9f7f961624 --- /dev/null +++ b/queue-4.9/scsi-qla2xxx-replace-fcport-alloc-with-qla2x00_alloc_fcport.patch @@ -0,0 +1,35 @@ +From 063b36d6b0ad74c748d536f5cb47bac2f850a0fa Mon Sep 17 00:00:00 2001 +From: Quinn Tran +Date: Mon, 4 Dec 2017 14:45:10 -0800 +Subject: scsi: qla2xxx: Replace fcport alloc with qla2x00_alloc_fcport + +From: Quinn Tran + +commit 063b36d6b0ad74c748d536f5cb47bac2f850a0fa upstream. + +Current code manually allocate an fcport structure that is not properly +initialize. Replace kzalloc with qla2x00_alloc_fcport, so that all +fields are initialized. Also set set scan flag to port found + +Cc: +Signed-off-by: Quinn Tran +Signed-off-by: Himanshu Madhani +Reviewed-by: Hannes Reinecke +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_target.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -5789,7 +5789,7 @@ static fc_port_t *qlt_get_port_database( + fc_port_t *fcport; + int rc; + +- fcport = kzalloc(sizeof(*fcport), GFP_KERNEL); ++ fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL); + if (!fcport) { + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06f, + "qla_target(%d): Allocation of tmp FC port failed", diff --git a/queue-4.9/series b/queue-4.9/series index 074c8d3125c..f89315a3ecb 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -61,3 +61,8 @@ netfilter-ipv6-fix-use-after-free-write-in-nf_nat_ipv6_manip_pkt.patch netfilter-x_tables-pass-xt_counters-struct-instead-of-packet-counter.patch netfilter-x_tables-pass-xt_counters-struct-to-counter-allocator.patch netfilter-x_tables-pack-percpu-counter-allocations.patch +ext4-inplace-xattr-block-update-fails-to-deduplicate-blocks.patch +ubi-fix-race-condition-between-ubi-volume-creation-and-udev.patch +scsi-qla2xxx-replace-fcport-alloc-with-qla2x00_alloc_fcport.patch +nfs-fix-an-incorrect-type-in-struct-nfs_direct_req.patch +nfs-fix-unstable-write-completion.patch diff --git a/queue-4.9/ubi-fix-race-condition-between-ubi-volume-creation-and-udev.patch b/queue-4.9/ubi-fix-race-condition-between-ubi-volume-creation-and-udev.patch new file mode 100644 index 00000000000..243679ff7cd --- /dev/null +++ b/queue-4.9/ubi-fix-race-condition-between-ubi-volume-creation-and-udev.patch @@ -0,0 +1,60 @@ +From a51a0c8d213594bc094cb8e54aad0cb6d7f7b9a6 Mon Sep 17 00:00:00 2001 +From: Clay McClure +Date: Thu, 21 Sep 2017 19:01:34 -0700 +Subject: ubi: Fix race condition between ubi volume creation and udev + +From: Clay McClure + +commit a51a0c8d213594bc094cb8e54aad0cb6d7f7b9a6 upstream. + +Similar to commit 714fb87e8bc0 ("ubi: Fix race condition between ubi +device creation and udev"), we should make the volume active before +registering it. + +Signed-off-by: Clay McClure +Cc: +Signed-off-by: Richard Weinberger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/ubi/vmt.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/drivers/mtd/ubi/vmt.c ++++ b/drivers/mtd/ubi/vmt.c +@@ -265,6 +265,12 @@ int ubi_create_volume(struct ubi_device + vol->last_eb_bytes = vol->usable_leb_size; + } + ++ /* Make volume "available" before it becomes accessible via sysfs */ ++ spin_lock(&ubi->volumes_lock); ++ ubi->volumes[vol_id] = vol; ++ ubi->vol_count += 1; ++ spin_unlock(&ubi->volumes_lock); ++ + /* Register character device for the volume */ + cdev_init(&vol->cdev, &ubi_vol_cdev_operations); + vol->cdev.owner = THIS_MODULE; +@@ -304,11 +310,6 @@ int ubi_create_volume(struct ubi_device + if (err) + goto out_sysfs; + +- spin_lock(&ubi->volumes_lock); +- ubi->volumes[vol_id] = vol; +- ubi->vol_count += 1; +- spin_unlock(&ubi->volumes_lock); +- + ubi_volume_notify(ubi, vol, UBI_VOLUME_ADDED); + self_check_volumes(ubi); + return err; +@@ -328,6 +329,10 @@ out_sysfs: + out_cdev: + cdev_del(&vol->cdev); + out_mapping: ++ spin_lock(&ubi->volumes_lock); ++ ubi->volumes[vol_id] = NULL; ++ ubi->vol_count -= 1; ++ spin_unlock(&ubi->volumes_lock); + if (do_free) + ubi_eba_destroy_table(eba_tbl); + out_acc: