Commit 8c61282f authored by Kinglong Mee's avatar Kinglong Mee Committed by Trond Myklebust

NFS: Get suppattr_exclcreat when getting server capabilities

Create file with attributs as NFS4_CREATE_EXCLUSIVE4_1 mode
depends on suppattr_exclcreat attribut.

v3, same as v2.
Signed-off-by: default avatarKinglong Mee <kinglongmee@gmail.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 5153aacf
...@@ -2893,8 +2893,10 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) ...@@ -2893,8 +2893,10 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
{ {
u32 bitmask[3] = {}, minorversion = server->nfs_client->cl_minorversion;
struct nfs4_server_caps_arg args = { struct nfs4_server_caps_arg args = {
.fhandle = fhandle, .fhandle = fhandle,
.bitmask = bitmask,
}; };
struct nfs4_server_caps_res res = {}; struct nfs4_server_caps_res res = {};
struct rpc_message msg = { struct rpc_message msg = {
...@@ -2904,10 +2906,18 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f ...@@ -2904,10 +2906,18 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
}; };
int status; int status;
bitmask[0] = FATTR4_WORD0_SUPPORTED_ATTRS |
FATTR4_WORD0_FH_EXPIRE_TYPE |
FATTR4_WORD0_LINK_SUPPORT |
FATTR4_WORD0_SYMLINK_SUPPORT |
FATTR4_WORD0_ACLSUPPORT;
if (minorversion)
bitmask[2] = FATTR4_WORD2_SUPPATTR_EXCLCREAT;
status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
if (status == 0) { if (status == 0) {
/* Sanity check the server answers */ /* Sanity check the server answers */
switch (server->nfs_client->cl_minorversion) { switch (minorversion) {
case 0: case 0:
res.attr_bitmask[1] &= FATTR4_WORD1_NFS40_MASK; res.attr_bitmask[1] &= FATTR4_WORD1_NFS40_MASK;
res.attr_bitmask[2] = 0; res.attr_bitmask[2] = 0;
...@@ -2960,6 +2970,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f ...@@ -2960,6 +2970,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE; server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE;
server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
server->cache_consistency_bitmask[2] = 0; server->cache_consistency_bitmask[2] = 0;
memcpy(server->exclcreat_bitmask, res.exclcreat_bitmask,
sizeof(server->exclcreat_bitmask));
server->acl_bitmask = res.acl_bitmask; server->acl_bitmask = res.acl_bitmask;
server->fh_expire_type = res.fh_expire_type; server->fh_expire_type = res.fh_expire_type;
} }
......
...@@ -2582,6 +2582,7 @@ static void nfs4_xdr_enc_server_caps(struct rpc_rqst *req, ...@@ -2582,6 +2582,7 @@ static void nfs4_xdr_enc_server_caps(struct rpc_rqst *req,
struct xdr_stream *xdr, struct xdr_stream *xdr,
struct nfs4_server_caps_arg *args) struct nfs4_server_caps_arg *args)
{ {
const u32 *bitmask = args->bitmask;
struct compound_hdr hdr = { struct compound_hdr hdr = {
.minorversion = nfs4_xdr_minorversion(&args->seq_args), .minorversion = nfs4_xdr_minorversion(&args->seq_args),
}; };
...@@ -2589,11 +2590,7 @@ static void nfs4_xdr_enc_server_caps(struct rpc_rqst *req, ...@@ -2589,11 +2590,7 @@ static void nfs4_xdr_enc_server_caps(struct rpc_rqst *req,
encode_compound_hdr(xdr, req, &hdr); encode_compound_hdr(xdr, req, &hdr);
encode_sequence(xdr, &args->seq_args, &hdr); encode_sequence(xdr, &args->seq_args, &hdr);
encode_putfh(xdr, args->fhandle, &hdr); encode_putfh(xdr, args->fhandle, &hdr);
encode_getattr_one(xdr, FATTR4_WORD0_SUPPORTED_ATTRS| encode_getattr_three(xdr, bitmask[0], bitmask[1], bitmask[2], &hdr);
FATTR4_WORD0_FH_EXPIRE_TYPE|
FATTR4_WORD0_LINK_SUPPORT|
FATTR4_WORD0_SYMLINK_SUPPORT|
FATTR4_WORD0_ACLSUPPORT, &hdr);
encode_nops(&hdr); encode_nops(&hdr);
} }
...@@ -3370,6 +3367,22 @@ static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t * ...@@ -3370,6 +3367,22 @@ static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t *
return -EIO; return -EIO;
} }
static int decode_attr_exclcreat_supported(struct xdr_stream *xdr,
uint32_t *bitmap, uint32_t *bitmask)
{
if (likely(bitmap[2] & FATTR4_WORD2_SUPPATTR_EXCLCREAT)) {
int ret;
ret = decode_attr_bitmap(xdr, bitmask);
if (unlikely(ret < 0))
return ret;
bitmap[2] &= ~FATTR4_WORD2_SUPPATTR_EXCLCREAT;
} else
bitmask[0] = bitmask[1] = bitmask[2] = 0;
dprintk("%s: bitmask=%08x:%08x:%08x\n", __func__,
bitmask[0], bitmask[1], bitmask[2]);
return 0;
}
static int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fh *fh) static int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fh *fh)
{ {
__be32 *p; __be32 *p;
...@@ -4323,6 +4336,9 @@ static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_re ...@@ -4323,6 +4336,9 @@ static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_re
goto xdr_error; goto xdr_error;
if ((status = decode_attr_aclsupport(xdr, bitmap, &res->acl_bitmask)) != 0) if ((status = decode_attr_aclsupport(xdr, bitmap, &res->acl_bitmask)) != 0)
goto xdr_error; goto xdr_error;
if ((status = decode_attr_exclcreat_supported(xdr, bitmap,
res->exclcreat_bitmask)) != 0)
goto xdr_error;
status = verify_attr_len(xdr, savep, attrlen); status = verify_attr_len(xdr, savep, attrlen);
xdr_error: xdr_error:
dprintk("%s: xdr returned %d!\n", __func__, -status); dprintk("%s: xdr returned %d!\n", __func__, -status);
......
...@@ -173,6 +173,11 @@ struct nfs_server { ...@@ -173,6 +173,11 @@ struct nfs_server {
set of attributes supported set of attributes supported
on this filesystem excluding on this filesystem excluding
the label support bit. */ the label support bit. */
u32 exclcreat_bitmask[3];
/* V4 bitmask representing the
set of attributes supported
on this filesystem for the
exclusive create. */
u32 cache_consistency_bitmask[3]; u32 cache_consistency_bitmask[3];
/* V4 bitmask representing the subset /* V4 bitmask representing the subset
of change attribute, size, ctime of change attribute, size, ctime
......
...@@ -1057,11 +1057,13 @@ struct nfs4_statfs_res { ...@@ -1057,11 +1057,13 @@ struct nfs4_statfs_res {
struct nfs4_server_caps_arg { struct nfs4_server_caps_arg {
struct nfs4_sequence_args seq_args; struct nfs4_sequence_args seq_args;
struct nfs_fh *fhandle; struct nfs_fh *fhandle;
const u32 * bitmask;
}; };
struct nfs4_server_caps_res { struct nfs4_server_caps_res {
struct nfs4_sequence_res seq_res; struct nfs4_sequence_res seq_res;
u32 attr_bitmask[3]; u32 attr_bitmask[3];
u32 exclcreat_bitmask[3];
u32 acl_bitmask; u32 acl_bitmask;
u32 has_links; u32 has_links;
u32 has_symlinks; u32 has_symlinks;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment