pnfs: Do not grab the commit_info lock twice when rescheduling writes

Acked-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: Tom Haynes <loghyr@primarydata.com>
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
index e5f841cb..fd2a2f0 100644
--- a/fs/nfs/pnfs_nfs.c
+++ b/fs/nfs/pnfs_nfs.c
@@ -66,7 +66,7 @@
 
 /* The generic layer is about to remove the req from the commit list.
  * If this will make the bucket empty, it will need to put the lseg reference.
- * Note this is must be called holding the inode (/cinfo) lock
+ * Note this must be called holding the inode (/cinfo) lock
  */
 void
 pnfs_generic_clear_request_commit(struct nfs_page *req,
@@ -115,7 +115,6 @@
 	return ret;
 }
 
-/* Note called with cinfo->lock held. */
 static int
 pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
 				 struct nfs_commit_info *cinfo,
@@ -125,6 +124,7 @@
 	struct list_head *dst = &bucket->committing;
 	int ret;
 
+	lockdep_assert_held(cinfo->lock);
 	ret = pnfs_generic_transfer_commit_list(src, dst, cinfo, max);
 	if (ret) {
 		cinfo->ds->nwritten -= ret;
@@ -138,14 +138,15 @@
 	return ret;
 }
 
-/* Move reqs from written to committing lists, returning count of number moved.
- * Note called with cinfo->lock held.
+/* Move reqs from written to committing lists, returning count
+ * of number moved.
  */
 int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo,
 				   int max)
 {
 	int i, rv = 0, cnt;
 
+	lockdep_assert_held(cinfo->lock);
 	for (i = 0; i < cinfo->ds->nbuckets && max != 0; i++) {
 		cnt = pnfs_generic_scan_ds_commit_list(&cinfo->ds->buckets[i],
 						       cinfo, max);
@@ -156,7 +157,7 @@
 }
 EXPORT_SYMBOL_GPL(pnfs_generic_scan_commit_lists);
 
-/* Pull everything off the committing lists and dump into @dst */
+/* Pull everything off the committing lists and dump into @dst.  */
 void pnfs_generic_recover_commit_reqs(struct list_head *dst,
 				      struct nfs_commit_info *cinfo)
 {
@@ -164,8 +165,8 @@
 	struct pnfs_layout_segment *freeme;
 	int i;
 
+	lockdep_assert_held(cinfo->lock);
 restart:
-	spin_lock(cinfo->lock);
 	for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) {
 		if (pnfs_generic_transfer_commit_list(&b->written, dst,
 						      cinfo, 0)) {
@@ -173,11 +174,11 @@
 			b->wlseg = NULL;
 			spin_unlock(cinfo->lock);
 			pnfs_put_lseg(freeme);
+			spin_lock(cinfo->lock);
 			goto restart;
 		}
 	}
 	cinfo->ds->nwritten = 0;
-	spin_unlock(cinfo->lock);
 }
 EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs);