diff options
author | Tom Haynes <loghyr@primarydata.com> | 2014-12-11 13:04:55 -0500 |
---|---|---|
committer | Tom Haynes <loghyr@primarydata.com> | 2015-02-03 14:06:31 -0500 |
commit | 085d1e33a6a8495d9afa58ad2b8b7ea74d613515 (patch) | |
tree | 3f39d90c0ccbce5f8f67ab3667304f18d22de70b /fs | |
parent | f54bcf2ecee982da47c2baf8bd87fd9ad9984651 (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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/direct.c | 19 | ||||
-rw-r--r-- | fs/nfs/pnfs.h | 15 | ||||
-rw-r--r-- | fs/nfs/pnfs_nfs.c | 15 |
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 | ||
576 | static void | ||
577 | nfs_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 | |||
576 | static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) | 590 | static 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 | ||
378 | static inline void | ||
379 | pnfs_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 | |||
387 | static inline struct nfs_page * | 378 | static inline struct nfs_page * |
388 | pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo, | 379 | pnfs_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 | ||
557 | static inline void | ||
558 | pnfs_recover_commit_reqs(struct inode *inode, struct list_head *list, | ||
559 | struct nfs_commit_info *cinfo) | ||
560 | { | ||
561 | } | ||
562 | |||
563 | static inline struct nfs_page * | 548 | static inline struct nfs_page * |
564 | pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo, | 549 | pnfs_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 | */ |
71 | void | 71 | void |
72 | pnfs_generic_clear_request_commit(struct nfs_page *req, | 72 | pnfs_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. */ | ||
119 | static int | 118 | static int |
120 | pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket, | 119 | pnfs_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 | */ |
144 | int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo, | 144 | int 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 | } |
157 | EXPORT_SYMBOL_GPL(pnfs_generic_scan_commit_lists); | 158 | EXPORT_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. */ |
160 | void pnfs_generic_recover_commit_reqs(struct list_head *dst, | 161 | void 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); | ||
167 | restart: | 169 | restart: |
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 | } |
182 | EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs); | 183 | EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs); |
183 | 184 | ||