aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Haynes <loghyr@primarydata.com>2014-12-11 13:04:55 -0500
committerTom Haynes <loghyr@primarydata.com>2015-02-03 14:06:31 -0500
commit085d1e33a6a8495d9afa58ad2b8b7ea74d613515 (patch)
tree3f39d90c0ccbce5f8f67ab3667304f18d22de70b
parentf54bcf2ecee982da47c2baf8bd87fd9ad9984651 (diff)
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>
-rw-r--r--fs/nfs/direct.c19
-rw-r--r--fs/nfs/pnfs.h15
-rw-r--r--fs/nfs/pnfs_nfs.c15
3 files changed, 23 insertions, 26 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 10bf07280f4a..e84f764b9dcd 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -573,6 +573,20 @@ out:
573 return result; 573 return result;
574} 574}
575 575
576static void
577nfs_direct_write_scan_commit_list(struct inode *inode,
578 struct list_head *list,
579 struct nfs_commit_info *cinfo)
580{
581 spin_lock(cinfo->lock);
582#ifdef CONFIG_NFS_V4_1
583 if (cinfo->ds != NULL && cinfo->ds->nwritten != 0)
584 NFS_SERVER(inode)->pnfs_curr_ld->recover_commit_reqs(list, cinfo);
585#endif
586 nfs_scan_commit_list(&cinfo->mds->list, list, cinfo, 0);
587 spin_unlock(cinfo->lock);
588}
589
576static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) 590static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
577{ 591{
578 struct nfs_pageio_descriptor desc; 592 struct nfs_pageio_descriptor desc;
@@ -582,10 +596,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
582 LIST_HEAD(failed); 596 LIST_HEAD(failed);
583 597
584 nfs_init_cinfo_from_dreq(&cinfo, dreq); 598 nfs_init_cinfo_from_dreq(&cinfo, dreq);
585 pnfs_recover_commit_reqs(dreq->inode, &reqs, &cinfo); 599 nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo);
586 spin_lock(cinfo.lock);
587 nfs_scan_commit_list(&cinfo.mds->list, &reqs, &cinfo, 0);
588 spin_unlock(cinfo.lock);
589 600
590 dreq->count = 0; 601 dreq->count = 0;
591 get_dreq(dreq); 602 get_dreq(dreq);
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index f17663446acc..e94f6050e9b1 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -375,15 +375,6 @@ pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo,
375 return NFS_SERVER(inode)->pnfs_curr_ld->scan_commit_lists(cinfo, max); 375 return NFS_SERVER(inode)->pnfs_curr_ld->scan_commit_lists(cinfo, max);
376} 376}
377 377
378static inline void
379pnfs_recover_commit_reqs(struct inode *inode, struct list_head *list,
380 struct nfs_commit_info *cinfo)
381{
382 if (cinfo->ds == NULL || cinfo->ds->nwritten == 0)
383 return;
384 NFS_SERVER(inode)->pnfs_curr_ld->recover_commit_reqs(list, cinfo);
385}
386
387static inline struct nfs_page * 378static inline struct nfs_page *
388pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo, 379pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
389 struct page *page) 380 struct page *page)
@@ -554,12 +545,6 @@ pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo,
554 return 0; 545 return 0;
555} 546}
556 547
557static inline void
558pnfs_recover_commit_reqs(struct inode *inode, struct list_head *list,
559 struct nfs_commit_info *cinfo)
560{
561}
562
563static inline struct nfs_page * 548static inline struct nfs_page *
564pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo, 549pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
565 struct page *page) 550 struct page *page)
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
index e5f841cb6227..fd2a2f0e8cbb 100644
--- a/fs/nfs/pnfs_nfs.c
+++ b/fs/nfs/pnfs_nfs.c
@@ -66,7 +66,7 @@ EXPORT_SYMBOL_GPL(pnfs_generic_commit_release);
66 66
67/* The generic layer is about to remove the req from the commit list. 67/* The generic layer is about to remove the req from the commit list.
68 * If this will make the bucket empty, it will need to put the lseg reference. 68 * If this will make the bucket empty, it will need to put the lseg reference.
69 * Note this is must be called holding the inode (/cinfo) lock 69 * Note this must be called holding the inode (/cinfo) lock
70 */ 70 */
71void 71void
72pnfs_generic_clear_request_commit(struct nfs_page *req, 72pnfs_generic_clear_request_commit(struct nfs_page *req,
@@ -115,7 +115,6 @@ pnfs_generic_transfer_commit_list(struct list_head *src, struct list_head *dst,
115 return ret; 115 return ret;
116} 116}
117 117
118/* Note called with cinfo->lock held. */
119static int 118static int
120pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket, 119pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
121 struct nfs_commit_info *cinfo, 120 struct nfs_commit_info *cinfo,
@@ -125,6 +124,7 @@ pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
125 struct list_head *dst = &bucket->committing; 124 struct list_head *dst = &bucket->committing;
126 int ret; 125 int ret;
127 126
127 lockdep_assert_held(cinfo->lock);
128 ret = pnfs_generic_transfer_commit_list(src, dst, cinfo, max); 128 ret = pnfs_generic_transfer_commit_list(src, dst, cinfo, max);
129 if (ret) { 129 if (ret) {
130 cinfo->ds->nwritten -= ret; 130 cinfo->ds->nwritten -= ret;
@@ -138,14 +138,15 @@ pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
138 return ret; 138 return ret;
139} 139}
140 140
141/* Move reqs from written to committing lists, returning count of number moved. 141/* Move reqs from written to committing lists, returning count
142 * Note called with cinfo->lock held. 142 * of number moved.
143 */ 143 */
144int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo, 144int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo,
145 int max) 145 int max)
146{ 146{
147 int i, rv = 0, cnt; 147 int i, rv = 0, cnt;
148 148
149 lockdep_assert_held(cinfo->lock);
149 for (i = 0; i < cinfo->ds->nbuckets && max != 0; i++) { 150 for (i = 0; i < cinfo->ds->nbuckets && max != 0; i++) {
150 cnt = pnfs_generic_scan_ds_commit_list(&cinfo->ds->buckets[i], 151 cnt = pnfs_generic_scan_ds_commit_list(&cinfo->ds->buckets[i],
151 cinfo, max); 152 cinfo, max);
@@ -156,7 +157,7 @@ int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo,
156} 157}
157EXPORT_SYMBOL_GPL(pnfs_generic_scan_commit_lists); 158EXPORT_SYMBOL_GPL(pnfs_generic_scan_commit_lists);
158 159
159/* Pull everything off the committing lists and dump into @dst */ 160/* Pull everything off the committing lists and dump into @dst. */
160void pnfs_generic_recover_commit_reqs(struct list_head *dst, 161void pnfs_generic_recover_commit_reqs(struct list_head *dst,
161 struct nfs_commit_info *cinfo) 162 struct nfs_commit_info *cinfo)
162{ 163{
@@ -164,8 +165,8 @@ void pnfs_generic_recover_commit_reqs(struct list_head *dst,
164 struct pnfs_layout_segment *freeme; 165 struct pnfs_layout_segment *freeme;
165 int i; 166 int i;
166 167
168 lockdep_assert_held(cinfo->lock);
167restart: 169restart:
168 spin_lock(cinfo->lock);
169 for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) { 170 for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) {
170 if (pnfs_generic_transfer_commit_list(&b->written, dst, 171 if (pnfs_generic_transfer_commit_list(&b->written, dst,
171 cinfo, 0)) { 172 cinfo, 0)) {
@@ -173,11 +174,11 @@ restart:
173 b->wlseg = NULL; 174 b->wlseg = NULL;
174 spin_unlock(cinfo->lock); 175 spin_unlock(cinfo->lock);
175 pnfs_put_lseg(freeme); 176 pnfs_put_lseg(freeme);
177 spin_lock(cinfo->lock);
176 goto restart; 178 goto restart;
177 } 179 }
178 } 180 }
179 cinfo->ds->nwritten = 0; 181 cinfo->ds->nwritten = 0;
180 spin_unlock(cinfo->lock);
181} 182}
182EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs); 183EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs);
183 184