fs/nfs/delegation.c
Source file repositories/reference/linux-study-clean/fs/nfs/delegation.c
File Facts
- System
- Linux kernel
- Corpus path
fs/nfs/delegation.c- Extension
.c- Size
- 44788 bytes
- Lines
- 1613
- 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.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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
linux/completion.hlinux/kthread.hlinux/module.hlinux/sched.hlinux/slab.hlinux/spinlock.hlinux/iversion.hlinux/nfs4.hlinux/nfs_fs.hlinux/nfs_xdr.hnfs4_fs.hnfs4session.hdelegation.hinternal.hnfs4trace.h
Detected Declarations
function __nfs_free_delegationfunction nfs_mark_delegation_revokedfunction nfs_put_delegationfunction nfs_mark_delegation_referencedfunction nfs_mark_return_delegationfunction nfs4_is_valid_delegationfunction nfs4_do_check_delegationfunction nfs4_have_delegationfunction nfs4_check_delegationfunction nfs_delegation_claim_locksfunction nfs_delegation_claim_opensfunction nfs_inode_reclaim_delegationfunction nfs_do_return_delegationfunction nfs_start_delegation_returnfunction nfs_detach_delegations_lockedfunction nfs_detach_delegationfunction nfs_update_delegation_credfunction nfs_update_inplace_delegationfunction nfs_inode_set_delegationfunction nfs_end_delegation_returnfunction nfs_return_one_delegationfunction test_and_set_bitfunction nfs_server_return_marked_delegationsfunction nfs_delegations_over_limitfunction nfs_delegations_return_from_lrufunction nfs_delegation_add_lrufunction nfs_server_clear_delayed_delegationsfunction nfs_client_clear_delayed_delegationsfunction nfs_client_return_marked_delegationsfunction nfs4_clear_inodefunction nfs4_inode_return_delegationfunction nfs4_inode_set_return_delegation_on_closefunction nfs4_inode_return_delegation_on_closefunction nfs4_inode_make_writeablefunction nfs_mark_return_if_closed_delegationfunction nfs_server_mark_return_all_delegationsfunction list_for_each_entry_rcufunction nfs_delegation_run_state_managerfunction nfs_expire_all_delegationsfunction nfs_server_return_all_delegationsfunction nfs_mark_return_unused_delegation_typesfunction list_for_each_entry_rcufunction nfs_expire_unused_delegation_typesfunction nfs_revoke_delegationfunction nfs_delegation_mark_returnedfunction nfs_remove_bad_delegationfunction nfs_mark_return_unreferenced_delegationsfunction nfs_expire_unreferenced_delegations
Annotated Snippet
if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
delegation->change_attr = update->change_attr;
nfs_update_delegation_cred(delegation, update->cred);
/* smp_mb__before_atomic() is implicit due to xchg() */
clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
atomic_long_inc(&server->nr_active_delegations);
}
}
}
/**
* nfs_inode_set_delegation - set up a delegation on an inode
* @inode: inode to which delegation applies
* @cred: cred to use for subsequent delegation processing
* @type: delegation type
* @stateid: delegation stateid
* @pagemod_limit: write delegation "space_limit"
* @deleg_type: raw delegation type
*
* Returns zero on success, or a negative errno value.
*/
int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
fmode_t type, const nfs4_stateid *stateid,
unsigned long pagemod_limit, u32 deleg_type)
{
struct nfs_server *server = NFS_SERVER(inode);
struct nfs_client *clp = server->nfs_client;
struct nfs_inode *nfsi = NFS_I(inode);
struct nfs_delegation *delegation, *old_delegation;
struct nfs_delegation *freeme = NULL;
int status = 0;
delegation = kmalloc_obj(*delegation, GFP_KERNEL_ACCOUNT);
if (delegation == NULL)
return -ENOMEM;
nfs4_stateid_copy(&delegation->stateid, stateid);
refcount_set(&delegation->refcount, 1);
delegation->type = type;
delegation->pagemod_limit = pagemod_limit;
delegation->change_attr = inode_peek_iversion_raw(inode);
delegation->cred = get_cred(cred);
delegation->inode = inode;
delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
INIT_LIST_HEAD(&delegation->entry);
switch (deleg_type) {
case NFS4_OPEN_DELEGATE_READ_ATTRS_DELEG:
case NFS4_OPEN_DELEGATE_WRITE_ATTRS_DELEG:
delegation->flags |= BIT(NFS_DELEGATION_DELEGTIME);
}
delegation->test_gen = 0;
spin_lock_init(&delegation->lock);
spin_lock(&clp->cl_lock);
old_delegation = rcu_dereference_protected(nfsi->delegation,
lockdep_is_held(&clp->cl_lock));
if (old_delegation == NULL)
goto add_new;
/* Is this an update of the existing delegation? */
if (nfs4_stateid_match_other(&old_delegation->stateid,
&delegation->stateid)) {
spin_lock(&old_delegation->lock);
nfs_update_inplace_delegation(server, old_delegation,
delegation);
spin_unlock(&old_delegation->lock);
goto out;
}
if (!test_bit(NFS_DELEGATION_REVOKED, &old_delegation->flags)) {
/*
* Deal with broken servers that hand out two
* delegations for the same file.
* Allow for upgrades to a WRITE delegation, but
* nothing else.
*/
dfprintk(FILE, "%s: server %s handed out "
"a duplicate delegation!\n",
__func__, clp->cl_hostname);
if (delegation->type == old_delegation->type ||
!(delegation->type & FMODE_WRITE)) {
freeme = delegation;
delegation = NULL;
goto out;
}
if (test_and_set_bit(NFS_DELEGATION_RETURNING,
&old_delegation->flags))
goto out;
}
if (!nfs_detach_delegations_locked(nfsi, old_delegation, clp))
goto out;
freeme = old_delegation;
add_new:
Annotation
- Immediate include surface: `linux/completion.h`, `linux/kthread.h`, `linux/module.h`, `linux/sched.h`, `linux/slab.h`, `linux/spinlock.h`, `linux/iversion.h`, `linux/nfs4.h`.
- Detected declarations: `function __nfs_free_delegation`, `function nfs_mark_delegation_revoked`, `function nfs_put_delegation`, `function nfs_mark_delegation_referenced`, `function nfs_mark_return_delegation`, `function nfs4_is_valid_delegation`, `function nfs4_do_check_delegation`, `function nfs4_have_delegation`, `function nfs4_check_delegation`, `function nfs_delegation_claim_locks`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: integration implementation candidate.
- 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.