delegation
struct delegation deleg;
int fcntl_getdeleg(struct file *filp, struct delegation *deleg)
int fcntl_setdeleg(unsigned int fd, struct file *filp, struct delegation *deleg)
struct nfs_delegation *delegation;
delegation = nfs4_get_valid_delegation(inode);
if (!delegation)
if ((delegation->type & FMODE_WRITE) == 0) {
nfs_put_delegation(delegation);
res->change_attr = delegation->change_attr;
nfs_put_delegation(delegation);
struct nfs_delegation *delegation;
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE))
if (delegation->type & flags)
nfs_mark_return_if_closed_delegation(server, delegation);
struct nfs_delegation *delegation;
delegation = rcu_dereference(NFS_I(inode)->delegation);
if (delegation == NULL)
nfs4_stateid_copy(&tmp, &delegation->stateid);
static bool nfs4_is_valid_delegation(const struct nfs_delegation *delegation,
if (!nfs4_stateid_match_other(stateid, &delegation->stateid))
spin_lock(&delegation->lock);
if (nfs4_stateid_is_newer(&delegation->stateid, stateid)) {
spin_unlock(&delegation->lock);
delegation->stateid.seqid = stateid->seqid;
spin_unlock(&delegation->lock);
nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
struct nfs_delegation *delegation;
delegation = rcu_dereference(NFS_I(inode)->delegation);
if (delegation != NULL && (delegation->type & type) == type &&
if (!delegation)
spin_lock(&delegation->lock);
if (!nfs4_stateid_match_other(stateid, &delegation->stateid))
if (nfs4_stateid_is_newer(&delegation->stateid, stateid))
!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
if (delegation->stateid.seqid != stateid->seqid)
delegation->stateid.seqid = stateid->seqid;
nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
spin_unlock(&delegation->lock);
if (nfs_detach_delegation(NFS_I(inode), delegation, NFS_SERVER(inode)))
nfs_put_delegation(delegation);
!test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
spin_unlock(&delegation->lock);
struct nfs_delegation *delegation;
struct nfs_delegation *delegation;
delegation = nfs4_get_valid_delegation(inode);
if (!delegation)
!clp->cl_mvops->match_stateid(&delegation->stateid, stateid)) {
nfs_put_delegation(delegation);
nfs_mark_return_delegation(server, delegation);
nfs_put_delegation(delegation);
delegation = rcu_dereference(NFS_I(inode)->delegation);
struct nfs_delegation *delegation;
if (!nfs4_is_valid_delegation(delegation, 0) ||
hlist_for_each_entry_rcu(delegation, head, hash) {
spin_lock(&delegation->lock);
if (delegation->inode != NULL &&
!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
res = igrab(delegation->inode);
spin_unlock(&delegation->lock);
!refcount_inc_not_zero(&delegation->refcount))
spin_unlock(&delegation->lock);
delegation = NULL;
return delegation;
struct nfs_delegation *delegation;
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
if (test_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags))
set_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
struct nfs_delegation *delegation;
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
&delegation->flags) ||
&delegation->flags) == 0)
inode = nfs_delegation_grab_inode(delegation);
delegation = nfs_start_delegation_return(NFS_I(inode));
if (delegation != NULL) {
if (nfs_detach_delegation(NFS_I(inode), delegation,
nfs_mark_delegation_revoked(server, delegation);
nfs_put_delegation(delegation);
nfs_put_delegation(delegation);
struct nfs_delegation *delegation;
struct nfs_delegation *delegation)
if (delegation->stateid.type == NFS4_INVALID_STATEID_TYPE)
clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
set_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
struct nfs_delegation *delegation;
delegation = rcu_dereference(NFS_I(inode)->delegation);
if (delegation)
nfs_mark_test_expired_delegation(server, delegation);
struct nfs_delegation *delegation;
delegation = rcu_dereference(NFS_I(inode)->delegation);
list_for_each_entry_rcu(delegation, &server->delegations, super_list)
nfs_mark_test_expired_delegation(server, delegation);
if (nfs4_is_valid_delegation(delegation, type)) {
nfs_mark_delegation_referenced(delegation);
struct nfs_delegation *delegation;
!test_bit(NFS_DELEGATION_DELEGTIME, &delegation->flags))
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
&delegation->flags) ||
&delegation->flags) == 0 ||
delegation->test_gen == gen)
inode = nfs_delegation_grab_inode(delegation);
spin_lock(&delegation->lock);
cred = get_cred_rcu(delegation->cred);
nfs4_stateid_copy(&stateid, &delegation->stateid);
spin_unlock(&delegation->lock);
delegation->test_gen = gen;
clear_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
struct nfs_delegation *delegation;
delegation = rcu_dereference(NFS_I(inode)->delegation);
if (delegation &&
nfs4_stateid_match_or_older(&delegation->stateid, stateid) &&
!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
nfs_mark_test_expired_delegation(NFS_SERVER(inode), delegation);
struct nfs_delegation *delegation;
delegation = rcu_dereference(NFS_I(inode)->delegation);
if (delegation != NULL &&
nfs4_stateid_match_other(dst, &delegation->stateid) &&
nfs4_stateid_is_newer(&delegation->stateid, dst) &&
!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
dst->seqid = delegation->stateid.seqid;
struct nfs_delegation *delegation;
delegation = rcu_dereference(nfsi->delegation);
if (!delegation)
spin_lock(&delegation->lock);
ret = nfs4_is_valid_delegation(delegation, flags);
nfs4_stateid_copy(dst, &delegation->stateid);
nfs_mark_delegation_referenced(delegation);
*cred = get_cred(delegation->cred);
spin_unlock(&delegation->lock);
struct nfs_delegation *delegation;
delegation = rcu_dereference(nfsi->delegation);
if (delegation == NULL || !(delegation->type & FMODE_WRITE))
if (atomic_long_read(&nfsi->nrequests) < delegation->pagemod_limit)
struct nfs_delegation *delegation;
delegation = rcu_dereference(NFS_I(inode)->delegation);
if (!delegation) {
spin_lock(&delegation->lock);
nfs4_stateid_copy(&delegation->stateid, stateid);
delegation->type = type;
delegation->pagemod_limit = pagemod_limit;
oldcred = delegation->cred;
delegation->cred = get_cred(cred);
set_bit(NFS_DELEGATION_DELEGTIME, &delegation->flags);
clear_bit(NFS_DELEGATION_DELEGTIME, &delegation->flags);
clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
if (test_and_clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
spin_unlock(&delegation->lock);
struct nfs_delegation *delegation,
if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
spin_lock(&delegation->lock);
cred = get_cred(delegation->cred);
spin_unlock(&delegation->lock);
res = nfs4_proc_delegreturn(inode, cred, &delegation->stateid,
delegation, issync);
static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation)
spin_lock(&delegation->lock);
if (delegation->inode != NULL)
inode = igrab(delegation->inode);
spin_unlock(&delegation->lock);
struct nfs_delegation *delegation;
delegation = rcu_dereference(nfsi->delegation);
if (!delegation || !refcount_inc_not_zero(&delegation->refcount)) {
spin_lock(&delegation->lock);
if (delegation->inode &&
!test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
spin_unlock(&delegation->lock);
nfs_put_delegation(delegation);
return delegation;
struct nfs_delegation *delegation,
trace_nfs4_detach_delegation(&nfsi->vfs_inode, delegation->type);
spin_lock(&delegation->lock);
if (!delegation->inode) {
spin_unlock(&delegation->lock);
hlist_del_init_rcu(&delegation->hash);
list_del_rcu(&delegation->super_list);
delegation->inode = NULL;
rcu_assign_pointer(nfsi->delegation, NULL);
spin_unlock(&delegation->lock);
struct nfs_delegation *delegation,
deleg_cur = rcu_dereference_protected(nfsi->delegation,
if (delegation == deleg_cur)
ret = nfs_detach_delegations_locked(nfsi, delegation, clp);
nfs_update_delegation_cred(struct nfs_delegation *delegation,
if (cred_fscmp(delegation->cred, cred) != 0) {
old = xchg(&delegation->cred, get_cred(cred));
struct nfs_delegation *delegation,
if (nfs4_stateid_is_newer(&update->stateid, &delegation->stateid)) {
delegation->stateid.seqid = update->stateid.seqid;
delegation->type = update->type;
delegation->pagemod_limit = update->pagemod_limit;
if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
delegation->change_attr = update->change_attr;
nfs_update_delegation_cred(delegation, update->cred);
clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
struct nfs_delegation *delegation, *old_delegation;
static void __nfs_free_delegation(struct nfs_delegation *delegation)
delegation = kmalloc_obj(*delegation, GFP_KERNEL_ACCOUNT);
if (delegation == NULL)
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);
delegation->flags |= BIT(NFS_DELEGATION_DELEGTIME);
delegation->test_gen = 0;
put_cred(delegation->cred);
spin_lock_init(&delegation->lock);
old_delegation = rcu_dereference_protected(nfsi->delegation,
&delegation->stateid)) {
delegation->cred = NULL;
delegation);
kfree_rcu(delegation, rcu);
if (delegation->type == old_delegation->type ||
!(delegation->type & FMODE_WRITE)) {
freeme = delegation;
delegation = NULL;
list_add_tail_rcu(&delegation->super_list, &server->delegations);
hlist_add_head_rcu(&delegation->hash,
rcu_assign_pointer(nfsi->delegation, delegation);
struct nfs_delegation *delegation)
delegation = NULL;
if (delegation != NULL)
__nfs_free_delegation(delegation);
struct nfs_delegation *delegation, bool issync)
if (test_and_set_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
err = nfs_delegation_claim_opens(inode, &delegation->stateid,
delegation->type);
return nfs_do_return_delegation(inode, delegation, issync);
if (list_empty(&delegation->entry))
refcount_inc(&delegation->refcount);
list_move_tail(&delegation->entry, &server->delegations_return);
delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;
clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
struct nfs_delegation *delegation;
delegation = list_first_entry_or_null(&server->delegations_return,
if (!delegation) {
list_del_init(&delegation->entry);
if (!test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
spin_lock(&delegation->lock);
inode = delegation->inode;
spin_unlock(&delegation->lock);
if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) ||
test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) {
spin_unlock(&delegation->lock);
nfs_clear_verifier_delegated(delegation->inode);
spin_unlock(&delegation->lock);
err = nfs_end_delegation_return(inode, delegation, false);
nfs_put_delegation(delegation);
if (!list_empty(&delegation->entry)) {
list_del_init(&delegation->entry);
struct nfs_delegation *delegation)
if (list_empty(&delegation->entry)) {
list_add_tail(&delegation->entry, &server->delegations_lru);
refcount_inc(&delegation->refcount);
nfs_put_delegation(delegation);
void nfs_put_delegation(struct nfs_delegation *delegation)
if (refcount_dec_and_test(&delegation->refcount))
struct nfs_delegation *delegation;
delegation = rcu_dereference(nfsi->delegation);
if (delegation && !nfs_detach_delegation(nfsi, delegation, server))
delegation = NULL;
__nfs_free_delegation(delegation);
if (!delegation)
set_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
nfs_do_return_delegation(inode, delegation, 1);
nfs_mark_delegation_revoked(server, delegation);
nfs_put_delegation(delegation);
struct nfs_delegation *delegation;
delegation = nfs_start_delegation_return(nfsi);
if (!delegation)
nfs_end_delegation_return(inode, delegation, true);
nfs_put_delegation(delegation);
struct nfs_delegation *delegation;
delegation = nfs4_get_valid_delegation(inode);
if (!delegation)
spin_lock(&delegation->lock);
if (!delegation->inode)
!test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
spin_unlock(&delegation->lock);
nfs_end_delegation_return(inode, delegation, false);
nfs_put_delegation(delegation);
void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
struct nfs_delegation *delegation;
delegation = nfs4_get_valid_delegation(inode);
if (!delegation)
if (test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags)) {
spin_lock(&delegation->lock);
if (delegation->inode &&
!test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) {
clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
spin_unlock(&delegation->lock);
set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
nfs_end_delegation_return(inode, delegation, false);
nfs_delegation_add_lru(server, delegation);
nfs_put_delegation(delegation);
struct nfs_delegation *delegation;
delegation = nfs4_get_valid_delegation(inode);
if (!delegation)
!(delegation->type & FMODE_WRITE))
nfs_put_delegation(delegation);
struct nfs_delegation *delegation)
test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags))
struct nfs_delegation *delegation)
spin_lock(&delegation->lock);
inode = delegation->inode;
nfs_mark_return_delegation(server, delegation);
set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
spin_unlock(&delegation->lock);
struct nfs_delegation *delegation;
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
nfs_mark_return_delegation(server, delegation);
if (list_empty(&delegation->entry))
refcount_inc(&delegation->refcount);
list_move_tail(&delegation->entry, &server->delegations_return);
struct nfs_delegation *delegation, int issync);
void nfs_put_delegation(struct nfs_delegation *delegation);
void nfs_mark_delegation_referenced(struct nfs_delegation *delegation);
nfsi->delegation = NULL;
if (rcu_access_pointer(NFS_I(state->inode)->delegation) != NULL)
struct nfs_delegation *delegation;
delegation = nfs4_get_valid_delegation(inode);
if (!delegation)
if ((delegation->type & fmode) != fmode)
if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags))
nfs_mark_delegation_referenced(delegation);
nfs4_stateid_copy(stateid, &delegation->stateid);
nfs_put_delegation(delegation);
const nfs4_stateid *delegation,
if (delegation == NULL)
delegation = &deleg_cur->stateid;
else if (!nfs4_stateid_match_other(&deleg_cur->stateid, delegation))
struct nfs_delegation *delegation;
delegation = nfs4_get_valid_delegation(inode);
if (!delegation)
if ((delegation->type & fmode) != fmode)
nfs_put_delegation(delegation);
const struct nfs4_open_delegation *delegation)
switch (delegation->open_delegation_type) {
nfs_inode_reclaim_delegation(inode, cred, delegation->type,
&delegation->stateid,
delegation->pagemod_limit,
delegation->open_delegation_type);
nfs_inode_set_delegation(inode, cred, delegation->type,
&delegation->stateid,
delegation->pagemod_limit,
delegation->open_delegation_type);
if (delegation->do_recall)
nfs_async_inode_return_delegation(inode, &delegation->stateid);
&data->o_res.delegation);
&data->o_res.delegation);
struct nfs_delegation *delegation;
delegation = rcu_dereference(NFS_I(state->inode)->delegation);
if (delegation != NULL && test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) != 0) {
switch(delegation->type) {
if (test_bit(NFS_DELEGATION_DELEGTIME, &delegation->flags))
if (test_bit(NFS_DELEGATION_DELEGTIME, &delegation->flags))
nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid);
struct nfs_delegation *delegation;
delegation = rcu_dereference(NFS_I(state->inode)->delegation);
if (delegation == NULL) {
spin_lock(&delegation->lock);
nfs4_stateid_copy(&stateid, &delegation->stateid);
&delegation->flags)) {
spin_unlock(&delegation->lock);
if (delegation->cred)
cred = get_cred(delegation->cred);
spin_unlock(&delegation->lock);
if (opendata->o_res.delegation.type != 0)
struct nfs_delegation *delegation,
if (delegation &&
test_bit(NFS_DELEGATION_DELEGTIME, &delegation->flags)) {
if (delegation->type & FMODE_READ) {
if (delegation->type & FMODE_WRITE) {
struct nfs_delegation *delegation, int issync)
delegation, issync);
TP_ARGS(delegation),
__entry->fhandle = nfs_fhandle_hash(NFS_FH(delegation->inode));
__entry->fmode = delegation->type;
__entry->flags = delegation->flags;
const struct nfs_delegation *delegation \
TP_ARGS(delegation))
const struct nfs_delegation *delegation
encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation);
encode_claim_delegate_cur_fh(xdr, &arg->u.delegation);
return decode_delegation(xdr, &res->delegation);
int fcntl_setdeleg(unsigned int fd, struct file *filp, struct delegation *deleg);
int fcntl_getdeleg(struct file *filp, struct delegation *deleg);
static inline int fcntl_setdeleg(unsigned int fd, struct file *filp, struct delegation *deleg)
static inline int fcntl_getdeleg(struct file *filp, struct delegation *deleg)
struct nfs_delegation __rcu *delegation;
nfs4_stateid delegation; /* CLAIM_DELEGATE_CUR */
struct nfs4_open_delegation delegation;