mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 08:58:07 +00:00
NFSv4: Add CB_GETATTR support for delegated attributes
When the client holds an attribute delegation, the server may retrieve all the timestamps through a CB_GETATTR callback. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Lance Shelton <lance.shelton@hammerspace.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
90f9ae7442
commit
43df7110f4
3 changed files with 49 additions and 9 deletions
|
@ -46,14 +46,15 @@ struct cb_compound_hdr_res {
|
|||
|
||||
struct cb_getattrargs {
|
||||
struct nfs_fh fh;
|
||||
uint32_t bitmap[2];
|
||||
uint32_t bitmap[3];
|
||||
};
|
||||
|
||||
struct cb_getattrres {
|
||||
__be32 status;
|
||||
uint32_t bitmap[2];
|
||||
uint32_t bitmap[3];
|
||||
uint64_t size;
|
||||
uint64_t change_attr;
|
||||
struct timespec64 atime;
|
||||
struct timespec64 ctime;
|
||||
struct timespec64 mtime;
|
||||
};
|
||||
|
|
|
@ -37,7 +37,7 @@ __be32 nfs4_callback_getattr(void *argp, void *resp,
|
|||
if (!cps->clp) /* Always set for v4.0. Set in cb_sequence for v4.1 */
|
||||
goto out;
|
||||
|
||||
res->bitmap[0] = res->bitmap[1] = 0;
|
||||
memset(res->bitmap, 0, sizeof(res->bitmap));
|
||||
res->status = htonl(NFS4ERR_BADHANDLE);
|
||||
|
||||
dprintk_rcu("NFS: GETATTR callback request from %s\n",
|
||||
|
@ -59,12 +59,16 @@ __be32 nfs4_callback_getattr(void *argp, void *resp,
|
|||
res->change_attr = delegation->change_attr;
|
||||
if (nfs_have_writebacks(inode))
|
||||
res->change_attr++;
|
||||
res->atime = inode_get_atime(inode);
|
||||
res->ctime = inode_get_ctime(inode);
|
||||
res->mtime = inode_get_mtime(inode);
|
||||
res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &
|
||||
args->bitmap[0];
|
||||
res->bitmap[1] = (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) &
|
||||
args->bitmap[1];
|
||||
res->bitmap[0] = (FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE) &
|
||||
args->bitmap[0];
|
||||
res->bitmap[1] = (FATTR4_WORD1_TIME_ACCESS |
|
||||
FATTR4_WORD1_TIME_METADATA |
|
||||
FATTR4_WORD1_TIME_MODIFY) & args->bitmap[1];
|
||||
res->bitmap[2] = (FATTR4_WORD2_TIME_DELEG_ACCESS |
|
||||
FATTR4_WORD2_TIME_DELEG_MODIFY) & args->bitmap[2];
|
||||
res->status = 0;
|
||||
out_iput:
|
||||
rcu_read_unlock();
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
#define CB_OP_GETATTR_BITMAP_MAXSZ (4 * 4) // bitmap length, 3 bitmaps
|
||||
#define CB_OP_GETATTR_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \
|
||||
CB_OP_GETATTR_BITMAP_MAXSZ + \
|
||||
/* change, size, ctime, mtime */\
|
||||
(2 + 2 + 3 + 3) * 4)
|
||||
/* change, size, atime, ctime,
|
||||
* mtime, deleg_atime, deleg_mtime */\
|
||||
(2 + 2 + 3 + 3 + 3 + 3 + 3) * 4)
|
||||
#define CB_OP_RECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
|
||||
|
||||
#if defined(CONFIG_NFS_V4_1)
|
||||
|
@ -635,6 +636,13 @@ static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec64 *
|
|||
return 0;
|
||||
}
|
||||
|
||||
static __be32 encode_attr_atime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec64 *time)
|
||||
{
|
||||
if (!(bitmap[1] & FATTR4_WORD1_TIME_ACCESS))
|
||||
return 0;
|
||||
return encode_attr_time(xdr,time);
|
||||
}
|
||||
|
||||
static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec64 *time)
|
||||
{
|
||||
if (!(bitmap[1] & FATTR4_WORD1_TIME_METADATA))
|
||||
|
@ -649,6 +657,24 @@ static __be32 encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap,
|
|||
return encode_attr_time(xdr,time);
|
||||
}
|
||||
|
||||
static __be32 encode_attr_delegatime(struct xdr_stream *xdr,
|
||||
const uint32_t *bitmap,
|
||||
const struct timespec64 *time)
|
||||
{
|
||||
if (!(bitmap[2] & FATTR4_WORD2_TIME_DELEG_ACCESS))
|
||||
return 0;
|
||||
return encode_attr_time(xdr,time);
|
||||
}
|
||||
|
||||
static __be32 encode_attr_delegmtime(struct xdr_stream *xdr,
|
||||
const uint32_t *bitmap,
|
||||
const struct timespec64 *time)
|
||||
{
|
||||
if (!(bitmap[2] & FATTR4_WORD2_TIME_DELEG_MODIFY))
|
||||
return 0;
|
||||
return encode_attr_time(xdr,time);
|
||||
}
|
||||
|
||||
static __be32 encode_compound_hdr_res(struct xdr_stream *xdr, struct cb_compound_hdr_res *hdr)
|
||||
{
|
||||
__be32 status;
|
||||
|
@ -697,12 +723,21 @@ static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr,
|
|||
if (unlikely(status != 0))
|
||||
goto out;
|
||||
status = encode_attr_size(xdr, res->bitmap, res->size);
|
||||
if (unlikely(status != 0))
|
||||
goto out;
|
||||
status = encode_attr_atime(xdr, res->bitmap, &res->atime);
|
||||
if (unlikely(status != 0))
|
||||
goto out;
|
||||
status = encode_attr_ctime(xdr, res->bitmap, &res->ctime);
|
||||
if (unlikely(status != 0))
|
||||
goto out;
|
||||
status = encode_attr_mtime(xdr, res->bitmap, &res->mtime);
|
||||
if (unlikely(status != 0))
|
||||
goto out;
|
||||
status = encode_attr_delegatime(xdr, res->bitmap, &res->atime);
|
||||
if (unlikely(status != 0))
|
||||
goto out;
|
||||
status = encode_attr_delegmtime(xdr, res->bitmap, &res->mtime);
|
||||
*savep = htonl((unsigned int)((char *)xdr->p - (char *)(savep+1)));
|
||||
out:
|
||||
return status;
|
||||
|
|
Loading…
Reference in a new issue