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.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
crypto/md5.hcrypto/sha2.hlinux/file.hlinux/slab.hlinux/namei.hlinux/sched.hlinux/fs.hlinux/hex.hlinux/module.hnet/net_namespace.hlinux/sunrpc/rpc_pipe_fs.hlinux/sunrpc/clnt.hlinux/nfsd/cld.hnfsd.hstate.hvfs.hnetns.h
Detected Declarations
struct nfsd4_client_tracking_opsstruct name_liststruct nfs4_dir_ctxstruct cld_netstruct cld_upcallfunction nfs4_save_credsfunction nfs4_reset_credsfunction nfs4_make_rec_clidnamefunction __nfsd4_create_reclaim_record_gracefunction nfsd4_create_clid_dirfunction nfsd4_build_namelistfunction nfsd4_list_rec_dirfunction list_for_each_entry_safefunction list_for_each_entry_safefunction nfsd4_unlink_clid_dirfunction __nfsd4_remove_reclaim_record_gracefunction nfsd4_remove_clid_dirfunction purge_oldfunction nfsd4_recdir_purge_oldfunction load_recdirfunction nfsd4_recdir_loadfunction nfsd4_init_recdirfunction nfsd4_shutdown_recdirfunction nfs4_legacy_state_initfunction nfs4_legacy_state_shutdownfunction nfsd4_load_reboot_recovery_datafunction nfsd4_legacy_tracking_initfunction nfsd4_legacy_tracking_exitfunction nfs4_reset_recoverydirfunction nfs4_recoverydirfunction nfsd4_check_legacy_clientfunction __cld_pipe_upcallfunction cld_pipe_upcallfunction __cld_pipe_inprogress_downcallfunction cld_pipe_downcallfunction listfunction cld_pipe_destroy_msgfunction nfsd4_cld_register_sbfunction nfsd4_cld_register_netfunction nfsd4_cld_unregister_netfunction __nfsd4_init_cld_pipefunction nfsd4_init_cld_pipefunction nfsd4_remove_cld_pipefunction alloc_cld_upcallfunction free_cld_upcallfunction nfsd4_cld_createfunction nfsd4_cld_create_v2function nfsd4_cld_remove
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
- Immediate include surface: `crypto/md5.h`, `crypto/sha2.h`, `linux/file.h`, `linux/slab.h`, `linux/namei.h`, `linux/sched.h`, `linux/fs.h`, `linux/hex.h`.
- Detected declarations: `struct nfsd4_client_tracking_ops`, `struct name_list`, `struct nfs4_dir_ctx`, `struct cld_net`, `struct cld_upcall`, `function nfs4_save_creds`, `function nfs4_reset_creds`, `function nfs4_make_rec_clidname`, `function __nfsd4_create_reclaim_record_grace`, `function nfsd4_create_clid_dir`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.