Commit 86e1c54d authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker
Browse files

NFSv4: Add recovery of attribute delegations



After a reboot of the NFSv4.2 server, the recovery code needs to specify
whether the delegation to be recovered is an attribute delegation or
not.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: default avatarLance Shelton <lance.shelton@hammerspace.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent e12912d9
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -2225,7 +2225,7 @@ static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
{
	struct nfs_delegation *delegation;
	struct nfs4_opendata *opendata;
	fmode_t delegation_type = 0;
	u32 delegation_type = NFS4_OPEN_DELEGATE_NONE;
	int status;

	opendata = nfs4_open_recoverdata_alloc(ctx, state,
@@ -2234,8 +2234,20 @@ static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
		return PTR_ERR(opendata);
	rcu_read_lock();
	delegation = rcu_dereference(NFS_I(state->inode)->delegation);
	if (delegation != NULL && test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) != 0)
		delegation_type = delegation->type;
	if (delegation != NULL && test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) != 0) {
		switch(delegation->type) {
		case FMODE_READ:
			delegation_type = NFS4_OPEN_DELEGATE_READ;
			if (test_bit(NFS_DELEGATION_DELEGTIME, &delegation->flags))
				delegation_type = NFS4_OPEN_DELEGATE_READ_ATTRS_DELEG;
			break;
		case FMODE_WRITE:
		case FMODE_READ|FMODE_WRITE:
			delegation_type = NFS4_OPEN_DELEGATE_WRITE;
			if (test_bit(NFS_DELEGATION_DELEGTIME, &delegation->flags))
				delegation_type = NFS4_OPEN_DELEGATE_WRITE_ATTRS_DELEG;
		}
	}
	rcu_read_unlock();
	opendata->o_arg.u.delegation_type = delegation_type;
	status = nfs4_open_recover(opendata, state);
+8 −10
Original line number Diff line number Diff line
@@ -1475,20 +1475,18 @@ static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *a
	}
}

static inline void encode_delegation_type(struct xdr_stream *xdr, fmode_t delegation_type)
static inline void encode_delegation_type(struct xdr_stream *xdr, u32 delegation_type)
{
	__be32 *p;

	p = reserve_space(xdr, 4);
	switch (delegation_type) {
	case 0:
		*p = cpu_to_be32(NFS4_OPEN_DELEGATE_NONE);
		break;
	case FMODE_READ:
		*p = cpu_to_be32(NFS4_OPEN_DELEGATE_READ);
		break;
	case FMODE_WRITE|FMODE_READ:
		*p = cpu_to_be32(NFS4_OPEN_DELEGATE_WRITE);
	case NFS4_OPEN_DELEGATE_NONE:
	case NFS4_OPEN_DELEGATE_READ:
	case NFS4_OPEN_DELEGATE_WRITE:
	case NFS4_OPEN_DELEGATE_READ_ATTRS_DELEG:
	case NFS4_OPEN_DELEGATE_WRITE_ATTRS_DELEG:
		*p = cpu_to_be32(delegation_type);
		break;
	default:
		BUG();
@@ -1504,7 +1502,7 @@ static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr *
	encode_string(xdr, name->len, name->name);
}

static inline void encode_claim_previous(struct xdr_stream *xdr, fmode_t type)
static inline void encode_claim_previous(struct xdr_stream *xdr, u32 type)
{
	__be32 *p;

+1 −1
Original line number Diff line number Diff line
@@ -484,7 +484,7 @@ struct nfs_openargs {
			nfs4_verifier   verifier; /* EXCLUSIVE */
		};
		nfs4_stateid	delegation;		/* CLAIM_DELEGATE_CUR */
		fmode_t		delegation_type;	/* CLAIM_PREVIOUS */
		__u32		delegation_type;	/* CLAIM_PREVIOUS */
	} u;
	const struct qstr *	name;
	const struct nfs_server *server;	 /* Needed for ID mapping */