fs/nfs/flexfilelayout/flexfilelayoutdev.c

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

File Facts

System
Linux kernel
Corpus path
fs/nfs/flexfilelayout/flexfilelayoutdev.c
Extension
.c
Size
18105 bytes
Lines
645
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source 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 (match > 0) {
			/* Add entry "dserr" _before_ entry "err" */
			head = &err->list;
			break;
		}
		/* Entries match, so merge "err" into "dserr" */
		extend_ds_error(dserr, err->offset, err->length);
		list_replace(&err->list, &dserr->list);
		kfree(err);
		return;
	}

	list_add_tail(&dserr->list, head);
}

int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
			     struct nfs4_ff_layout_mirror *mirror,
			     u32 dss_id, u64 offset, u64 length, int status,
			     enum nfs_opnum4 opnum, gfp_t gfp_flags)
{
	struct nfs4_ff_layout_ds_err *dserr;

	if (status == 0)
		return 0;

	if (IS_ERR_OR_NULL(mirror->dss[dss_id].mirror_ds))
		return -EINVAL;

	dserr = kmalloc_obj(*dserr, gfp_flags);
	if (!dserr)
		return -ENOMEM;

	INIT_LIST_HEAD(&dserr->list);
	dserr->offset = offset;
	dserr->length = length;
	dserr->status = status;
	dserr->opnum = opnum;
	nfs4_stateid_copy(&dserr->stateid, &mirror->dss[dss_id].stateid);
	memcpy(&dserr->deviceid, &mirror->dss[dss_id].mirror_ds->id_node.deviceid,
	       NFS4_DEVICEID4_SIZE);

	spin_lock(&flo->generic_hdr.plh_inode->i_lock);
	ff_layout_add_ds_error_locked(flo, dserr);
	spin_unlock(&flo->generic_hdr.plh_inode->i_lock);
	return 0;
}

static const struct cred *
ff_layout_get_mirror_cred(struct nfs4_ff_layout_mirror *mirror, u32 iomode, u32 dss_id)
{
	const struct cred *cred, __rcu **pcred;

	if (iomode == IOMODE_READ)
		pcred = &mirror->dss[dss_id].ro_cred;
	else
		pcred = &mirror->dss[dss_id].rw_cred;

	rcu_read_lock();
	do {
		cred = rcu_dereference(*pcred);
		if (!cred)
			break;

		cred = get_cred_rcu(cred);
	} while(!cred);
	rcu_read_unlock();
	return cred;
}

struct nfs_fh *
nfs4_ff_layout_select_ds_fh(struct nfs4_ff_layout_mirror *mirror, u32 dss_id)
{
	/* FIXME: For now assume there is only 1 version available for the DS */
	return &mirror->dss[dss_id].fh_versions[0];
}

void
nfs4_ff_layout_select_ds_stateid(const struct nfs4_ff_layout_mirror *mirror,
				 u32 dss_id,
				 nfs4_stateid *stateid)
{
	if (nfs4_ff_layout_ds_version(mirror, dss_id) == 4)
		nfs4_stateid_copy(stateid, &mirror->dss[dss_id].stateid);
}

static bool
ff_layout_init_mirror_ds(struct pnfs_layout_hdr *lo,
			 struct nfs4_ff_layout_mirror *mirror,
			 u32 dss_id)
{

Annotation

Implementation Notes