|
@@ -51,6 +51,7 @@
|
|
|
#include <linux/nfs_fs.h>
|
|
|
#include <linux/nfs_idmap.h>
|
|
|
#include "nfs4_fs.h"
|
|
|
+#include "internal.h"
|
|
|
|
|
|
#define NFSDBG_FACILITY NFSDBG_XDR
|
|
|
|
|
@@ -134,7 +135,7 @@ static int nfs4_stat_to_errno(int);
|
|
|
#define decode_lookup_maxsz (op_decode_hdr_maxsz)
|
|
|
#define encode_share_access_maxsz \
|
|
|
(2)
|
|
|
-#define encode_createmode_maxsz (1 + encode_attrs_maxsz)
|
|
|
+#define encode_createmode_maxsz (1 + encode_attrs_maxsz + encode_verifier_maxsz)
|
|
|
#define encode_opentype_maxsz (1 + encode_createmode_maxsz)
|
|
|
#define encode_claim_null_maxsz (1 + nfs4_name_maxsz)
|
|
|
#define encode_open_maxsz (op_encode_hdr_maxsz + \
|
|
@@ -1140,6 +1141,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
|
|
|
static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
|
|
|
{
|
|
|
__be32 *p;
|
|
|
+ struct nfs_client *clp;
|
|
|
|
|
|
p = reserve_space(xdr, 4);
|
|
|
switch(arg->open_flags & O_EXCL) {
|
|
@@ -1148,8 +1150,23 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op
|
|
|
encode_attrs(xdr, arg->u.attrs, arg->server);
|
|
|
break;
|
|
|
default:
|
|
|
- *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
|
|
|
- encode_nfs4_verifier(xdr, &arg->u.verifier);
|
|
|
+ clp = arg->server->nfs_client;
|
|
|
+ if (clp->cl_minorversion > 0) {
|
|
|
+ if (nfs4_has_persistent_session(clp)) {
|
|
|
+ *p = cpu_to_be32(NFS4_CREATE_GUARDED);
|
|
|
+ encode_attrs(xdr, arg->u.attrs, arg->server);
|
|
|
+ } else {
|
|
|
+ struct iattr dummy;
|
|
|
+
|
|
|
+ *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1);
|
|
|
+ encode_nfs4_verifier(xdr, &arg->u.verifier);
|
|
|
+ dummy.ia_valid = 0;
|
|
|
+ encode_attrs(xdr, &dummy, arg->server);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
|
|
|
+ encode_nfs4_verifier(xdr, &arg->u.verifier);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|