fs/nfs/pnfs_nfs.c

Source file repositories/reference/linux-study-clean/fs/nfs/pnfs_nfs.c

File Facts

System
Linux kernel
Corpus path
fs/nfs/pnfs_nfs.c
Extension
.c
Size
31137 bytes
Lines
1226
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (freeme) {
			pnfs_put_lseg(freeme);
			goto restart;
		}
	}
	return ret;
}

/* Pull everything off the committing lists and dump into @dst.  */
void pnfs_generic_recover_commit_reqs(struct list_head *dst,
				      struct nfs_commit_info *cinfo)
{
	struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
	struct pnfs_commit_array *array;
	unsigned int nwritten;

	lockdep_assert_held(&NFS_I(cinfo->inode)->commit_mutex);
	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);

static struct pnfs_layout_segment *
pnfs_bucket_get_committing(struct list_head *head,
			   struct pnfs_commit_bucket *bucket,
			   struct nfs_commit_info *cinfo)
{
	struct pnfs_layout_segment *lseg;
	struct list_head *pos;

	list_for_each(pos, &bucket->committing)
		cinfo->ds->ncommitting--;
	list_splice_init(&bucket->committing, head);
	lseg = pnfs_free_bucket_lseg(bucket);
	if (!lseg)
		lseg = pnfs_get_lseg(bucket->lseg);
	return lseg;
}

static struct nfs_commit_data *
pnfs_bucket_fetch_commitdata(struct pnfs_commit_bucket *bucket,
			     struct nfs_commit_info *cinfo)
{
	struct nfs_commit_data *data = nfs_commitdata_alloc();

	if (!data)
		return NULL;
	data->lseg = pnfs_bucket_get_committing(&data->pages, bucket, cinfo);
	return data;
}

static void pnfs_generic_retry_commit(struct pnfs_commit_bucket *buckets,
				      unsigned int nbuckets,
				      struct nfs_commit_info *cinfo,
				      unsigned int idx)
{
	struct pnfs_commit_bucket *bucket;
	struct pnfs_layout_segment *freeme;
	LIST_HEAD(pages);

	for (bucket = buckets; idx < nbuckets; bucket++, idx++) {
		if (list_empty(&bucket->committing))
			continue;
		mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
		freeme = pnfs_bucket_get_committing(&pages, bucket, cinfo);
		mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
		nfs_retry_commit(&pages, freeme, cinfo, idx);
		pnfs_put_lseg(freeme);
	}
}

static unsigned int
pnfs_bucket_alloc_ds_commits(struct list_head *list,
			     struct pnfs_commit_bucket *buckets,
			     unsigned int nbuckets,
			     struct nfs_commit_info *cinfo)
{
	struct pnfs_commit_bucket *bucket;

Annotation

Implementation Notes