pNFS: Add infrastructure for cleaning up per-layout commit structures
Ensure that both the file and flexfiles layout types clean up when freeing the layout segments. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
@@ -118,6 +118,67 @@ pnfs_free_commit_array(struct pnfs_commit_array *p)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_free_commit_array);
|
||||
|
||||
static void
|
||||
pnfs_release_commit_array_locked(struct pnfs_commit_array *array)
|
||||
{
|
||||
list_del_rcu(&array->cinfo_list);
|
||||
list_del(&array->lseg_list);
|
||||
pnfs_free_commit_array(array);
|
||||
}
|
||||
|
||||
static void
|
||||
pnfs_put_commit_array_locked(struct pnfs_commit_array *array)
|
||||
{
|
||||
if (refcount_dec_and_test(&array->refcount))
|
||||
pnfs_release_commit_array_locked(array);
|
||||
}
|
||||
|
||||
static void
|
||||
pnfs_put_commit_array(struct pnfs_commit_array *array, struct inode *inode)
|
||||
{
|
||||
if (refcount_dec_and_lock(&array->refcount, &inode->i_lock)) {
|
||||
pnfs_release_commit_array_locked(array);
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static struct pnfs_commit_array *
|
||||
pnfs_get_commit_array(struct pnfs_commit_array *array)
|
||||
{
|
||||
if (refcount_inc_not_zero(&array->refcount))
|
||||
return array;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
pnfs_remove_and_free_commit_array(struct pnfs_commit_array *array)
|
||||
{
|
||||
array->lseg = NULL;
|
||||
list_del_init(&array->lseg_list);
|
||||
pnfs_put_commit_array_locked(array);
|
||||
}
|
||||
|
||||
void
|
||||
pnfs_generic_ds_cinfo_release_lseg(struct pnfs_ds_commit_info *fl_cinfo,
|
||||
struct pnfs_layout_segment *lseg)
|
||||
{
|
||||
struct pnfs_commit_array *array, *tmp;
|
||||
|
||||
list_for_each_entry_safe(array, tmp, &lseg->pls_commits, lseg_list)
|
||||
pnfs_remove_and_free_commit_array(array);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_generic_ds_cinfo_release_lseg);
|
||||
|
||||
void
|
||||
pnfs_generic_ds_cinfo_destroy(struct pnfs_ds_commit_info *fl_cinfo)
|
||||
{
|
||||
struct pnfs_commit_array *array, *tmp;
|
||||
|
||||
list_for_each_entry_safe(array, tmp, &fl_cinfo->commits, cinfo_list)
|
||||
pnfs_remove_and_free_commit_array(array);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_generic_ds_cinfo_destroy);
|
||||
|
||||
/*
|
||||
* Locks the nfs_page requests for commit and moves them to
|
||||
* @bucket->committing.
|
||||
@@ -177,14 +238,21 @@ int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo, int max)
|
||||
max -= cnt;
|
||||
if (!max)
|
||||
return rv;
|
||||
list_for_each_entry(array, &fl_cinfo->commits, cinfo_list) {
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(array, &fl_cinfo->commits, cinfo_list) {
|
||||
if (!array->lseg || !pnfs_get_commit_array(array))
|
||||
continue;
|
||||
rcu_read_unlock();
|
||||
cnt = pnfs_bucket_scan_array(cinfo, array->buckets,
|
||||
array->nbuckets, max);
|
||||
rcu_read_lock();
|
||||
pnfs_put_commit_array(array, cinfo->inode);
|
||||
rv += cnt;
|
||||
max -= cnt;
|
||||
if (!max)
|
||||
break;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return rv;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_generic_scan_commit_lists);
|
||||
@@ -230,13 +298,20 @@ void pnfs_generic_recover_commit_reqs(struct list_head *dst,
|
||||
fl_cinfo->nbuckets,
|
||||
cinfo);
|
||||
fl_cinfo->nwritten -= nwritten;
|
||||
list_for_each_entry(array, &fl_cinfo->commits, cinfo_list) {
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(array, &fl_cinfo->commits, cinfo_list) {
|
||||
if (!array->lseg || !pnfs_get_commit_array(array))
|
||||
continue;
|
||||
rcu_read_unlock();
|
||||
nwritten = pnfs_bucket_recover_commit_reqs(dst,
|
||||
array->buckets,
|
||||
array->nbuckets,
|
||||
cinfo);
|
||||
rcu_read_lock();
|
||||
pnfs_put_commit_array(array, cinfo->inode);
|
||||
fl_cinfo->nwritten -= nwritten;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs);
|
||||
|
||||
@@ -330,9 +405,16 @@ pnfs_alloc_ds_commits_list(struct list_head *list,
|
||||
struct pnfs_commit_array *array;
|
||||
unsigned int ret = 0;
|
||||
|
||||
list_for_each_entry(array, &fl_cinfo->commits, cinfo_list)
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(array, &fl_cinfo->commits, cinfo_list) {
|
||||
if (!array->lseg || !pnfs_get_commit_array(array))
|
||||
continue;
|
||||
rcu_read_unlock();
|
||||
ret += pnfs_bucket_alloc_ds_commits(list, array->buckets,
|
||||
array->nbuckets, cinfo);
|
||||
rcu_read_lock();
|
||||
pnfs_put_commit_array(array, cinfo->inode);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user