[PATCH 4.14 044/140] pNFS: Prevent the layout header refcount going to zero in pnfs_roc()

2018-03-13 Thread Greg Kroah-Hartman
4.14-stable review patch.  If anyone has any objections, please let me know.

--

From: Trond Myklebust 

commit 9c6376ebddad585da4238532dd6d90ae23ffee67 upstream.

Ensure that we hold a reference to the layout header when processing
the pNFS return-on-close so that the refcount value does not inadvertently
go to zero.

Reported-by: Tigran Mkrtchyan 
Signed-off-by: Trond Myklebust 
Cc: sta...@vger.kernel.org # v4.10+
Tested-by: Tigran Mkrtchyan 
Signed-off-by: Greg Kroah-Hartman 

---
 fs/nfs/pnfs.c |   13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -292,8 +292,11 @@ pnfs_detach_layout_hdr(struct pnfs_layou
 void
 pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo)
 {
-   struct inode *inode = lo->plh_inode;
+   struct inode *inode;
 
+   if (!lo)
+   return;
+   inode = lo->plh_inode;
pnfs_layoutreturn_before_put_layout_hdr(lo);
 
if (atomic_dec_and_lock(>plh_refcount, >i_lock)) {
@@ -1223,10 +1226,12 @@ retry:
spin_lock(>i_lock);
lo = nfsi->layout;
if (!lo || !pnfs_layout_is_valid(lo) ||
-   test_bit(NFS_LAYOUT_BULK_RECALL, >plh_flags))
+   test_bit(NFS_LAYOUT_BULK_RECALL, >plh_flags)) {
+   lo = NULL;
goto out_noroc;
+   }
+   pnfs_get_layout_hdr(lo);
if (test_bit(NFS_LAYOUT_RETURN_LOCK, >plh_flags)) {
-   pnfs_get_layout_hdr(lo);
spin_unlock(>i_lock);
wait_on_bit(>plh_flags, NFS_LAYOUT_RETURN,
TASK_UNINTERRUPTIBLE);
@@ -1294,10 +1299,12 @@ out_noroc:
struct pnfs_layoutdriver_type *ld = 
NFS_SERVER(ino)->pnfs_curr_ld;
if (ld->prepare_layoutreturn)
ld->prepare_layoutreturn(args);
+   pnfs_put_layout_hdr(lo);
return true;
}
if (layoutreturn)
pnfs_send_layoutreturn(lo, , iomode, true);
+   pnfs_put_layout_hdr(lo);
return false;
 }
 




[PATCH 4.14 044/140] pNFS: Prevent the layout header refcount going to zero in pnfs_roc()

2018-03-13 Thread Greg Kroah-Hartman
4.14-stable review patch.  If anyone has any objections, please let me know.

--

From: Trond Myklebust 

commit 9c6376ebddad585da4238532dd6d90ae23ffee67 upstream.

Ensure that we hold a reference to the layout header when processing
the pNFS return-on-close so that the refcount value does not inadvertently
go to zero.

Reported-by: Tigran Mkrtchyan 
Signed-off-by: Trond Myklebust 
Cc: sta...@vger.kernel.org # v4.10+
Tested-by: Tigran Mkrtchyan 
Signed-off-by: Greg Kroah-Hartman 

---
 fs/nfs/pnfs.c |   13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -292,8 +292,11 @@ pnfs_detach_layout_hdr(struct pnfs_layou
 void
 pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo)
 {
-   struct inode *inode = lo->plh_inode;
+   struct inode *inode;
 
+   if (!lo)
+   return;
+   inode = lo->plh_inode;
pnfs_layoutreturn_before_put_layout_hdr(lo);
 
if (atomic_dec_and_lock(>plh_refcount, >i_lock)) {
@@ -1223,10 +1226,12 @@ retry:
spin_lock(>i_lock);
lo = nfsi->layout;
if (!lo || !pnfs_layout_is_valid(lo) ||
-   test_bit(NFS_LAYOUT_BULK_RECALL, >plh_flags))
+   test_bit(NFS_LAYOUT_BULK_RECALL, >plh_flags)) {
+   lo = NULL;
goto out_noroc;
+   }
+   pnfs_get_layout_hdr(lo);
if (test_bit(NFS_LAYOUT_RETURN_LOCK, >plh_flags)) {
-   pnfs_get_layout_hdr(lo);
spin_unlock(>i_lock);
wait_on_bit(>plh_flags, NFS_LAYOUT_RETURN,
TASK_UNINTERRUPTIBLE);
@@ -1294,10 +1299,12 @@ out_noroc:
struct pnfs_layoutdriver_type *ld = 
NFS_SERVER(ino)->pnfs_curr_ld;
if (ld->prepare_layoutreturn)
ld->prepare_layoutreturn(args);
+   pnfs_put_layout_hdr(lo);
return true;
}
if (layoutreturn)
pnfs_send_layoutreturn(lo, , iomode, true);
+   pnfs_put_layout_hdr(lo);
return false;
 }