Commit c84bea59 authored by Trond Myklebust's avatar Trond Myklebust

NFS/pNFS: Simplify bucket layout segment reference counting

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 9c455a8c
...@@ -59,6 +59,17 @@ void pnfs_generic_commit_release(void *calldata) ...@@ -59,6 +59,17 @@ void pnfs_generic_commit_release(void *calldata)
} }
EXPORT_SYMBOL_GPL(pnfs_generic_commit_release); EXPORT_SYMBOL_GPL(pnfs_generic_commit_release);
static struct pnfs_layout_segment *
pnfs_free_bucket_lseg(struct pnfs_commit_bucket *bucket)
{
if (list_empty(&bucket->committing) && list_empty(&bucket->written)) {
struct pnfs_layout_segment *freeme = bucket->lseg;
bucket->lseg = NULL;
return freeme;
}
return NULL;
}
/* 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 must be called holding nfsi->commit_mutex * Note this must be called holding nfsi->commit_mutex
...@@ -78,8 +89,7 @@ pnfs_generic_clear_request_commit(struct nfs_page *req, ...@@ -78,8 +89,7 @@ pnfs_generic_clear_request_commit(struct nfs_page *req,
bucket = list_first_entry(&req->wb_list, bucket = list_first_entry(&req->wb_list,
struct pnfs_commit_bucket, struct pnfs_commit_bucket,
written); written);
freeme = bucket->wlseg; freeme = pnfs_free_bucket_lseg(bucket);
bucket->wlseg = NULL;
} }
out: out:
nfs_request_remove_commit_list(req, cinfo); nfs_request_remove_commit_list(req, cinfo);
...@@ -103,8 +113,7 @@ pnfs_alloc_commit_array(size_t n, gfp_t gfp_flags) ...@@ -103,8 +113,7 @@ pnfs_alloc_commit_array(size_t n, gfp_t gfp_flags)
for (b = &p->buckets[0]; n != 0; b++, n--) { for (b = &p->buckets[0]; n != 0; b++, n--) {
INIT_LIST_HEAD(&b->written); INIT_LIST_HEAD(&b->written);
INIT_LIST_HEAD(&b->committing); INIT_LIST_HEAD(&b->committing);
b->wlseg = NULL; b->lseg = NULL;
b->clseg = NULL;
b->direct_verf.committed = NFS_INVALID_STABLE_HOW; b->direct_verf.committed = NFS_INVALID_STABLE_HOW;
} }
return p; return p;
...@@ -246,12 +255,6 @@ pnfs_bucket_scan_ds_commit_list(struct pnfs_commit_bucket *bucket, ...@@ -246,12 +255,6 @@ pnfs_bucket_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
if (ret) { if (ret) {
cinfo->ds->nwritten -= ret; cinfo->ds->nwritten -= ret;
cinfo->ds->ncommitting += ret; cinfo->ds->ncommitting += ret;
if (bucket->clseg == NULL)
bucket->clseg = pnfs_get_lseg(bucket->wlseg);
if (list_empty(src)) {
pnfs_put_lseg(bucket->wlseg);
bucket->wlseg = NULL;
}
} }
return ret; return ret;
} }
...@@ -317,9 +320,8 @@ pnfs_bucket_recover_commit_reqs(struct list_head *dst, ...@@ -317,9 +320,8 @@ pnfs_bucket_recover_commit_reqs(struct list_head *dst,
if (!nwritten) if (!nwritten)
continue; continue;
ret += nwritten; ret += nwritten;
if (list_empty(&b->written)) { freeme = pnfs_free_bucket_lseg(b);
freeme = b->wlseg; if (freeme) {
b->wlseg = NULL;
pnfs_put_lseg(freeme); pnfs_put_lseg(freeme);
goto restart; goto restart;
} }
...@@ -405,15 +407,12 @@ pnfs_bucket_get_committing(struct list_head *head, ...@@ -405,15 +407,12 @@ pnfs_bucket_get_committing(struct list_head *head,
struct pnfs_commit_bucket *bucket, struct pnfs_commit_bucket *bucket,
struct nfs_commit_info *cinfo) struct nfs_commit_info *cinfo)
{ {
struct pnfs_layout_segment *freeme;
struct list_head *pos; struct list_head *pos;
list_for_each(pos, &bucket->committing) list_for_each(pos, &bucket->committing)
cinfo->ds->ncommitting--; cinfo->ds->ncommitting--;
list_splice_init(&bucket->committing, head); list_splice_init(&bucket->committing, head);
freeme = bucket->clseg; return pnfs_free_bucket_lseg(bucket);
bucket->clseg = NULL;
return freeme;
} }
static struct nfs_commit_data * static struct nfs_commit_data *
...@@ -425,6 +424,8 @@ pnfs_bucket_fetch_commitdata(struct pnfs_commit_bucket *bucket, ...@@ -425,6 +424,8 @@ pnfs_bucket_fetch_commitdata(struct pnfs_commit_bucket *bucket,
if (!data) if (!data)
return NULL; return NULL;
data->lseg = pnfs_bucket_get_committing(&data->pages, bucket, cinfo); data->lseg = pnfs_bucket_get_committing(&data->pages, bucket, cinfo);
if (!data->lseg)
data->lseg = pnfs_get_lseg(bucket->lseg);
return data; return data;
} }
...@@ -1182,8 +1183,8 @@ pnfs_layout_mark_request_commit(struct nfs_page *req, ...@@ -1182,8 +1183,8 @@ pnfs_layout_mark_request_commit(struct nfs_page *req,
* off due to a rewrite, in which case it will be done in * off due to a rewrite, in which case it will be done in
* pnfs_common_clear_request_commit * pnfs_common_clear_request_commit
*/ */
WARN_ON_ONCE(buckets[ds_commit_idx].wlseg != NULL); if (!buckets[ds_commit_idx].lseg)
buckets[ds_commit_idx].wlseg = pnfs_get_lseg(lseg); buckets[ds_commit_idx].lseg = pnfs_get_lseg(lseg);
} }
set_bit(PG_COMMIT_TO_DS, &req->wb_flags); set_bit(PG_COMMIT_TO_DS, &req->wb_flags);
cinfo->ds->nwritten++; cinfo->ds->nwritten++;
......
...@@ -1265,8 +1265,7 @@ struct nfstime4 { ...@@ -1265,8 +1265,7 @@ struct nfstime4 {
struct pnfs_commit_bucket { struct pnfs_commit_bucket {
struct list_head written; struct list_head written;
struct list_head committing; struct list_head committing;
struct pnfs_layout_segment *wlseg; struct pnfs_layout_segment *lseg;
struct pnfs_layout_segment *clseg;
struct nfs_writeverf direct_verf; struct nfs_writeverf direct_verf;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment