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>
This commit is contained in:
parent
f54bcf2ece
commit
085d1e33a6
|
@ -573,6 +573,20 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nfs_direct_write_scan_commit_list(struct inode *inode,
|
||||||
|
struct list_head *list,
|
||||||
|
struct nfs_commit_info *cinfo)
|
||||||
|
{
|
||||||
|
spin_lock(cinfo->lock);
|
||||||
|
#ifdef CONFIG_NFS_V4_1
|
||||||
|
if (cinfo->ds != NULL && cinfo->ds->nwritten != 0)
|
||||||
|
NFS_SERVER(inode)->pnfs_curr_ld->recover_commit_reqs(list, cinfo);
|
||||||
|
#endif
|
||||||
|
nfs_scan_commit_list(&cinfo->mds->list, list, cinfo, 0);
|
||||||
|
spin_unlock(cinfo->lock);
|
||||||
|
}
|
||||||
|
|
||||||
static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
|
static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
|
||||||
{
|
{
|
||||||
struct nfs_pageio_descriptor desc;
|
struct nfs_pageio_descriptor desc;
|
||||||
|
@ -582,10 +596,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
|
||||||
LIST_HEAD(failed);
|
LIST_HEAD(failed);
|
||||||
|
|
||||||
nfs_init_cinfo_from_dreq(&cinfo, dreq);
|
nfs_init_cinfo_from_dreq(&cinfo, dreq);
|
||||||
pnfs_recover_commit_reqs(dreq->inode, &reqs, &cinfo);
|
nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo);
|
||||||
spin_lock(cinfo.lock);
|
|
||||||
nfs_scan_commit_list(&cinfo.mds->list, &reqs, &cinfo, 0);
|
|
||||||
spin_unlock(cinfo.lock);
|
|
||||||
|
|
||||||
dreq->count = 0;
|
dreq->count = 0;
|
||||||
get_dreq(dreq);
|
get_dreq(dreq);
|
||||||
|
|
|
@ -375,15 +375,6 @@ pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo,
|
||||||
return NFS_SERVER(inode)->pnfs_curr_ld->scan_commit_lists(cinfo, max);
|
return NFS_SERVER(inode)->pnfs_curr_ld->scan_commit_lists(cinfo, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
pnfs_recover_commit_reqs(struct inode *inode, struct list_head *list,
|
|
||||||
struct nfs_commit_info *cinfo)
|
|
||||||
{
|
|
||||||
if (cinfo->ds == NULL || cinfo->ds->nwritten == 0)
|
|
||||||
return;
|
|
||||||
NFS_SERVER(inode)->pnfs_curr_ld->recover_commit_reqs(list, cinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct nfs_page *
|
static inline struct nfs_page *
|
||||||
pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
|
pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
|
||||||
struct page *page)
|
struct page *page)
|
||||||
|
@ -554,12 +545,6 @@ pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
pnfs_recover_commit_reqs(struct inode *inode, struct list_head *list,
|
|
||||||
struct nfs_commit_info *cinfo)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct nfs_page *
|
static inline struct nfs_page *
|
||||||
pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
|
pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
|
||||||
struct page *page)
|
struct page *page)
|
||||||
|
|
|
@ -66,7 +66,7 @@ EXPORT_SYMBOL_GPL(pnfs_generic_commit_release);
|
||||||
|
|
||||||
/* The generic layer is about to remove the req from the commit list.
|
/* 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.
|
* 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
|
void
|
||||||
pnfs_generic_clear_request_commit(struct nfs_page *req,
|
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,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note called with cinfo->lock held. */
|
|
||||||
static int
|
static int
|
||||||
pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
|
pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
|
||||||
struct nfs_commit_info *cinfo,
|
struct nfs_commit_info *cinfo,
|
||||||
|
@ -125,6 +124,7 @@ pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
|
||||||
struct list_head *dst = &bucket->committing;
|
struct list_head *dst = &bucket->committing;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
lockdep_assert_held(cinfo->lock);
|
||||||
ret = pnfs_generic_transfer_commit_list(src, dst, cinfo, max);
|
ret = pnfs_generic_transfer_commit_list(src, dst, cinfo, max);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
cinfo->ds->nwritten -= ret;
|
cinfo->ds->nwritten -= ret;
|
||||||
|
@ -138,14 +138,15 @@ pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move reqs from written to committing lists, returning count of number moved.
|
/* Move reqs from written to committing lists, returning count
|
||||||
* Note called with cinfo->lock held.
|
* of number moved.
|
||||||
*/
|
*/
|
||||||
int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo,
|
int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo,
|
||||||
int max)
|
int max)
|
||||||
{
|
{
|
||||||
int i, rv = 0, cnt;
|
int i, rv = 0, cnt;
|
||||||
|
|
||||||
|
lockdep_assert_held(cinfo->lock);
|
||||||
for (i = 0; i < cinfo->ds->nbuckets && max != 0; i++) {
|
for (i = 0; i < cinfo->ds->nbuckets && max != 0; i++) {
|
||||||
cnt = pnfs_generic_scan_ds_commit_list(&cinfo->ds->buckets[i],
|
cnt = pnfs_generic_scan_ds_commit_list(&cinfo->ds->buckets[i],
|
||||||
cinfo, max);
|
cinfo, max);
|
||||||
|
@ -156,7 +157,7 @@ int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pnfs_generic_scan_commit_lists);
|
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,
|
void pnfs_generic_recover_commit_reqs(struct list_head *dst,
|
||||||
struct nfs_commit_info *cinfo)
|
struct nfs_commit_info *cinfo)
|
||||||
{
|
{
|
||||||
|
@ -164,8 +165,8 @@ void pnfs_generic_recover_commit_reqs(struct list_head *dst,
|
||||||
struct pnfs_layout_segment *freeme;
|
struct pnfs_layout_segment *freeme;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
lockdep_assert_held(cinfo->lock);
|
||||||
restart:
|
restart:
|
||||||
spin_lock(cinfo->lock);
|
|
||||||
for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) {
|
for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) {
|
||||||
if (pnfs_generic_transfer_commit_list(&b->written, dst,
|
if (pnfs_generic_transfer_commit_list(&b->written, dst,
|
||||||
cinfo, 0)) {
|
cinfo, 0)) {
|
||||||
|
@ -173,11 +174,11 @@ void pnfs_generic_recover_commit_reqs(struct list_head *dst,
|
||||||
b->wlseg = NULL;
|
b->wlseg = NULL;
|
||||||
spin_unlock(cinfo->lock);
|
spin_unlock(cinfo->lock);
|
||||||
pnfs_put_lseg(freeme);
|
pnfs_put_lseg(freeme);
|
||||||
|
spin_lock(cinfo->lock);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cinfo->ds->nwritten = 0;
|
cinfo->ds->nwritten = 0;
|
||||||
spin_unlock(cinfo->lock);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs);
|
EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue