Home Home > GIT Browse > SLE15
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-09-13 09:19:13 +0200
committerTakashi Iwai <tiwai@suse.de>2017-09-13 09:19:13 +0200
commit3927ef50e05f402148c50e3531ad774a025d28e9 (patch)
tree871ea998cd5f98ad8ea05fdb928bfc0074e254b3
parent33fc95733bd5a30e47d5945a8d28d325f471b89a (diff)
parent3389c26bb1e6928dc895482dbbe84089cfbc155f (diff)
Merge branch 'SLE12-SP3' into openSUSE-42.3rpm-4.4.87-25
-rw-r--r--patches.fixes/0001-NFS-flush-data-when-locking-a-file-to-ensure-cache-c.patch80
-rw-r--r--patches.fixes/0001-md-raid5-fix-a-race-condition-in-stripe-batch.patch71
-rw-r--r--series.conf3
3 files changed, 154 insertions, 0 deletions
diff --git a/patches.fixes/0001-NFS-flush-data-when-locking-a-file-to-ensure-cache-c.patch b/patches.fixes/0001-NFS-flush-data-when-locking-a-file-to-ensure-cache-c.patch
new file mode 100644
index 0000000000..b95d291378
--- /dev/null
+++ b/patches.fixes/0001-NFS-flush-data-when-locking-a-file-to-ensure-cache-c.patch
@@ -0,0 +1,80 @@
+From: NeilBrown <neilb@suse.com>
+Date: Fri, 18 Aug 2017 17:12:52 +1000
+Subject: [PATCH] NFS: flush data when locking a file to ensure cache coherence
+ for mmap.
+Git-commit: 779eafab06036fe1e06dea9bbd97cc4b12f0138f
+Patch-mainline: v4.14
+References: bsc#981309
+
+When a byte range lock (or flock) is taken out on an NFS file, the
+validity of the cached data is checked and the inode is marked
+NFS_INODE_INVALID_DATA. However the cached data isn't flushed from
+the page cache.
+
+This is sufficient for future read() requests or mmap() requests as
+they call nfs_revalidate_mapping() which performs the flush if
+necessary.
+
+However an existing mapping is not affected. Accessing data through
+that mapping will continue to return old data even though the inode is
+marked NFS_INODE_INVALID_DATA.
+
+This can easily be confirmed using the 'nfs' tool in
+ git://github.com/okirch/twopence-nfs.git
+and running
+
+ nfs coherence FILENAME
+on one client, and
+ nfs coherence -r FILENAME
+on another client.
+
+It appears that prior to Linux 2.6.0 this worked correctly.
+
+However commit:
+
+http://git.kernel.org/cgit/linux/kernel/git/history/history.git/commit/?id=ca9268fe3ddd075714005adecd4afbd7f9ab87d0
+
+removed the call to inode_invalidate_pages() from nfs_zap_caches(). I
+haven't tested this code, but inspection suggests that prior to this
+commit, file locking would invalidate all inode pages.
+
+This patch adds a call to nfs_revalidate_mapping() after a
+successful SETLK so that invalid data is flushed. With this patch the
+above test passes. To minimize impact (and possibly avoid a GETATTR
+call) this only happens if the mapping might be mapped into
+userspace.
+
+Cc: Olaf Kirch <okir@suse.com>
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Acked-by: NeilBrown <neilb@suse.com>
+
+---
+ fs/nfs/file.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/fs/nfs/file.c
++++ b/fs/nfs/file.c
+@@ -811,15 +811,18 @@ do_setlk(struct file *filp, int cmd, str
+ goto out;
+
+ /*
+- * Revalidate the cache if the server has time stamps granular
+- * enough to detect subsecond changes. Otherwise, clear the
+- * cache to prevent missing any changes.
++ * Invalidate cache to prevent missing any changes. If
++ * the file is mapped, clear the page cache as well so
++ * those mappings will be loaded.
+ *
+ * This makes locking act as a cache coherency point.
+ */
+ nfs_sync_mapping(filp->f_mapping);
+- if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
++ if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) {
+ nfs_zap_caches(inode);
++ if (mapping_mapped(filp->f_mapping))
++ nfs_revalidate_mapping(inode, filp->f_mapping);
++ }
+ out:
+ return status;
+ }
diff --git a/patches.fixes/0001-md-raid5-fix-a-race-condition-in-stripe-batch.patch b/patches.fixes/0001-md-raid5-fix-a-race-condition-in-stripe-batch.patch
new file mode 100644
index 0000000000..b5b549dd4c
--- /dev/null
+++ b/patches.fixes/0001-md-raid5-fix-a-race-condition-in-stripe-batch.patch
@@ -0,0 +1,71 @@
+From: Shaohua Li <shli@fb.com>
+Date: Fri, 25 Aug 2017 10:40:02 -0700
+Subject: [PATCH] md/raid5: fix a race condition in stripe batch
+Git-commit: 3664847d95e60a9a943858b7800f8484669740fc
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/shli/md.git
+Patch-mainline: Queued in subsystem maintainer repository
+References: linux-stable
+
+We have a race condition in below scenario, say have 3 continuous stripes, sh1,
+sh2 and sh3, sh1 is the stripe_head of sh2 and sh3:
+
+CPU1 CPU2 CPU3
+handle_stripe(sh3)
+ stripe_add_to_batch_list(sh3)
+ -> lock(sh2, sh3)
+ -> lock batch_lock(sh1)
+ -> add sh3 to batch_list of sh1
+ -> unlock batch_lock(sh1)
+ clear_batch_ready(sh1)
+ -> lock(sh1) and batch_lock(sh1)
+ -> clear STRIPE_BATCH_READY for all stripes in batch_list
+ -> unlock(sh1) and batch_lock(sh1)
+->clear_batch_ready(sh3)
+-->test_and_clear_bit(STRIPE_BATCH_READY, sh3)
+
+Acked-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Neil Brown <neilb@suse.com>
+
+--->return 0 as sh->batch == NULL
+ -> sh3->batch_head = sh1
+ -> unlock (sh2, sh3)
+
+In CPU1, handle_stripe will continue handle sh3 even it's in batch stripe list
+of sh1. By moving sh3->batch_head assignment in to batch_lock, we make it
+impossible to clear STRIPE_BATCH_READY before batch_head is set.
+
+Thanks Stephane for helping debug this tricky issue.
+
+Reported-and-tested-by: Stephane Thiell <sthiell@stanford.edu>
+Cc: stable@vger.kernel.org (v4.1+)
+Signed-off-by: Shaohua Li <shli@fb.com>
+---
+ drivers/md/raid5.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -816,6 +816,14 @@ static void stripe_add_to_batch_list(str
+ spin_unlock(&head->batch_head->batch_lock);
+ goto unlock_out;
+ }
++ /*
++ * We must assign batch_head of this stripe within the
++ * batch_lock, otherwise clear_batch_ready of batch head
++ * stripe could clear BATCH_READY bit of this stripe and
++ * this stripe->batch_head doesn't get assigned, which
++ * could confuse clear_batch_ready for this stripe
++ */
++ sh->batch_head = head->batch_head;
+
+ /*
+ * at this point, head's BATCH_READY could be cleared, but we
+@@ -823,8 +831,6 @@ static void stripe_add_to_batch_list(str
+ */
+ list_add(&sh->batch_list, &head->batch_list);
+ spin_unlock(&head->batch_head->batch_lock);
+-
+- sh->batch_head = head->batch_head;
+ } else {
+ head->batch_head = head;
+ sh->batch_head = head->batch_head;
diff --git a/series.conf b/series.conf
index 36afff439d..7b76db482f 100644
--- a/series.conf
+++ b/series.conf
@@ -3637,6 +3637,7 @@
patches.fixes/0002-NFS-Cache-aggressively-when-file-is-open-for-writing.patch
patches.fixes/0001-NFS-invalidate-file-size-when-taking-a-lock.patch
patches.fixes/0002-NFS-Optimize-fallocate-by-refreshing-mapping-when-ne.patch
+ patches.fixes/0001-NFS-flush-data-when-locking-a-file-to-ensure-cache-c.patch
########################################################
# cifs patches
@@ -13266,6 +13267,8 @@
patches.fixes/0001-md-use-a-separate-bio_set-for-synchronous-IO.patch
patches.fixes/0001-MD-fix-sleep-in-atomic.patch
+ patches.fixes/0001-md-raid5-fix-a-race-condition-in-stripe-batch.patch
+
# FATE#321488, drivers/md back port upto 4.10, part 1
patches.drivers/0002-md-r5cache-Check-array-size-in-r5l_init_log.patch
patches.drivers/0003-md-r5cache-move-some-code-to-raid5.h.patch