fs/nfsd/nfs4recover.c

Source file repositories/reference/linux-study-clean/fs/nfsd/nfs4recover.c

File Facts

System
Linux kernel
Corpus path
fs/nfsd/nfs4recover.c
Extension
.c
Size
48813 bytes
Lines
2039
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

struct nfsd4_client_tracking_ops {
	int (*init)(struct net *);
	void (*exit)(struct net *);
	void (*create)(struct nfs4_client *);
	void (*remove)(struct nfs4_client *);
	int (*check)(struct nfs4_client *);
	void (*grace_done)(struct nfsd_net *);
	uint8_t version;
	size_t msglen;
};

static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops;
static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops_v2;

#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
/* Globals */
static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";

static int
nfs4_save_creds(const struct cred **original_creds)
{
	struct cred *new;

	new = prepare_creds();
	if (!new)
		return -ENOMEM;

	new->fsuid = GLOBAL_ROOT_UID;
	new->fsgid = GLOBAL_ROOT_GID;
	*original_creds = override_creds(new);
	return 0;
}

static void
nfs4_reset_creds(const struct cred *original)
{
	put_cred(revert_creds(original));
}

static void
nfs4_make_rec_clidname(char dname[HEXDIR_LEN], const struct xdr_netobj *clname)
{
	u8 digest[MD5_DIGEST_SIZE];

	dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
			clname->len, clname->data);

	md5(clname->data, clname->len, digest);

	static_assert(HEXDIR_LEN == 2 * MD5_DIGEST_SIZE + 1);
	sprintf(dname, "%*phN", MD5_DIGEST_SIZE, digest);
}

static void
__nfsd4_create_reclaim_record_grace(struct nfs4_client *clp,
				    char *dname, struct nfsd_net *nn)
{
	struct xdr_netobj name = { .len = strlen(dname), .data = dname };
	struct xdr_netobj princhash = { .len = 0, .data = NULL };
	struct nfs4_client_reclaim *crp;

	crp = nfs4_client_to_reclaim(name, princhash, nn);
	crp->cr_clp = clp;
}

static void
nfsd4_create_clid_dir(struct nfs4_client *clp)
{
	const struct cred *original_cred;
	char dname[HEXDIR_LEN];
	struct dentry *dir, *dentry;
	int status;
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

	if (test_and_set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
		return;
	if (!nn->rec_file)
		return;

	nfs4_make_rec_clidname(dname, &clp->cl_name);

	status = nfs4_save_creds(&original_cred);
	if (status < 0)
		return;

	status = mnt_want_write_file(nn->rec_file);
	if (status)
		goto out_creds;

	dir = nn->rec_file->f_path.dentry;

Annotation

Implementation Notes