Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79fb54ab authored by Benny Halevy's avatar Benny Halevy Committed by J. Bruce Fields
Browse files

nfsd41: CREATE_EXCLUSIVE4_1

Implement the CREATE_EXCLUSIVE4_1 open mode conforming to
http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-26



This mode allows the client to atomically create a file
if it doesn't exist while setting some of its attributes.

It must be implemented if the server supports persistent
reply cache and/or pnfs.

Signed-off-by: default avatarBenny Halevy <bhalevy@panasas.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
parent 8c18f205
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -93,6 +93,21 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
	open->op_truncate = 0;

	if (open->op_create) {
		/* FIXME: check session persistence and pnfs flags.
		 * The nfsv4.1 spec requires the following semantics:
		 *
		 * Persistent   | pNFS   | Server REQUIRED | Client Allowed
		 * Reply Cache  | server |                 |
		 * -------------+--------+-----------------+--------------------
		 * no           | no     | EXCLUSIVE4_1    | EXCLUSIVE4_1
		 *              |        |                 | (SHOULD)
		 *              |        | and EXCLUSIVE4  | or EXCLUSIVE4
		 *              |        |                 | (SHOULD NOT)
		 * no           | yes    | EXCLUSIVE4_1    | EXCLUSIVE4_1
		 * yes          | no     | GUARDED4        | GUARDED4
		 * yes          | yes    | GUARDED4        | GUARDED4
		 */

		/*
		 * Note: create modes (UNCHECKED,GUARDED...) are the same
		 * in NFSv4 as in v3.
+17 −0
Original line number Diff line number Diff line
@@ -260,6 +260,12 @@ static u32 nfsd_attrmask[] = {
	NFSD_WRITEABLE_ATTRS_WORD2
};

static u32 nfsd41_ex_attrmask[] = {
	NFSD_SUPPATTR_EXCLCREAT_WORD0,
	NFSD_SUPPATTR_EXCLCREAT_WORD1,
	NFSD_SUPPATTR_EXCLCREAT_WORD2
};

static __be32
nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable,
		   struct iattr *iattr, struct nfs4_acl **acl)
@@ -684,6 +690,17 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
			READ_BUF(8);
			COPYMEM(open->op_verf.data, 8);
			break;
		case NFS4_CREATE_EXCLUSIVE4_1:
			if (argp->minorversion < 1)
				goto xdr_error;
			READ_BUF(8);
			COPYMEM(open->op_verf.data, 8);
			status = nfsd4_decode_fattr(argp, open->op_bmval,
				nfsd41_ex_attrmask, &open->op_iattr,
				&open->op_acl);
			if (status)
				goto out;
			break;
		default:
			goto xdr_error;
		}
+7 −1
Original line number Diff line number Diff line
@@ -368,7 +368,13 @@ enum opentype4 {
enum createmode4 {
	NFS4_CREATE_UNCHECKED = 0,
	NFS4_CREATE_GUARDED = 1,
	NFS4_CREATE_EXCLUSIVE = 2
	NFS4_CREATE_EXCLUSIVE = 2,
	/*
	 * New to NFSv4.1. If session is persistent,
	 * GUARDED4 MUST be used. Otherwise, use
	 * EXCLUSIVE4_1 instead of EXCLUSIVE4.
	 */
	NFS4_CREATE_EXCLUSIVE4_1 = 3
};

enum limit_by4 {
+4 −6
Original line number Diff line number Diff line
@@ -219,10 +219,8 @@ struct nfsd4_open {
	u32		op_create;     	    /* request */
	u32		op_createmode;      /* request */
	u32		op_bmval[3];        /* request */
	union {                             /* request */
		struct iattr	iattr;                      /* UNCHECKED4,GUARDED4 */
	struct iattr	iattr;              /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */
	nfs4_verifier	verf;               /* EXCLUSIVE4 */
	} u;
	clientid_t	op_clientid;        /* request */
	struct xdr_netobj op_owner;           /* request */
	u32		op_seqid;           /* request */
@@ -236,8 +234,8 @@ struct nfsd4_open {
	struct nfs4_stateowner *op_stateowner; /* used during processing */
	struct nfs4_acl *op_acl;
};
#define op_iattr	u.iattr
#define op_verf		u.verf
#define op_iattr	iattr
#define op_verf		verf

struct nfsd4_open_confirm {
	stateid_t	oc_req_stateid		/* request */;