mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +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
@ -46,14 +46,15 @@ struct cb_compound_hdr_res {
|
|||||||
|
|
||||||
struct cb_getattrargs {
|
struct cb_getattrargs {
|
||||||
struct nfs_fh fh;
|
struct nfs_fh fh;
|
||||||
uint32_t bitmap[2];
|
uint32_t bitmap[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cb_getattrres {
|
struct cb_getattrres {
|
||||||
__be32 status;
|
__be32 status;
|
||||||
uint32_t bitmap[2];
|
uint32_t bitmap[3];
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
uint64_t change_attr;
|
uint64_t change_attr;
|
||||||
|
struct timespec64 atime;
|
||||||
struct timespec64 ctime;
|
struct timespec64 ctime;
|
||||||
struct timespec64 mtime;
|
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 */
|
if (!cps->clp) /* Always set for v4.0. Set in cb_sequence for v4.1 */
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
res->bitmap[0] = res->bitmap[1] = 0;
|
memset(res->bitmap, 0, sizeof(res->bitmap));
|
||||||
res->status = htonl(NFS4ERR_BADHANDLE);
|
res->status = htonl(NFS4ERR_BADHANDLE);
|
||||||
|
|
||||||
dprintk_rcu("NFS: GETATTR callback request from %s\n",
|
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;
|
res->change_attr = delegation->change_attr;
|
||||||
if (nfs_have_writebacks(inode))
|
if (nfs_have_writebacks(inode))
|
||||||
res->change_attr++;
|
res->change_attr++;
|
||||||
|
res->atime = inode_get_atime(inode);
|
||||||
res->ctime = inode_get_ctime(inode);
|
res->ctime = inode_get_ctime(inode);
|
||||||
res->mtime = inode_get_mtime(inode);
|
res->mtime = inode_get_mtime(inode);
|
||||||
res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &
|
res->bitmap[0] = (FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE) &
|
||||||
args->bitmap[0];
|
args->bitmap[0];
|
||||||
res->bitmap[1] = (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) &
|
res->bitmap[1] = (FATTR4_WORD1_TIME_ACCESS |
|
||||||
args->bitmap[1];
|
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;
|
res->status = 0;
|
||||||
out_iput:
|
out_iput:
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
@ -25,8 +25,9 @@
|
|||||||
#define CB_OP_GETATTR_BITMAP_MAXSZ (4 * 4) // bitmap length, 3 bitmaps
|
#define CB_OP_GETATTR_BITMAP_MAXSZ (4 * 4) // bitmap length, 3 bitmaps
|
||||||
#define CB_OP_GETATTR_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \
|
#define CB_OP_GETATTR_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \
|
||||||
CB_OP_GETATTR_BITMAP_MAXSZ + \
|
CB_OP_GETATTR_BITMAP_MAXSZ + \
|
||||||
/* change, size, ctime, mtime */\
|
/* change, size, atime, ctime,
|
||||||
(2 + 2 + 3 + 3) * 4)
|
* mtime, deleg_atime, deleg_mtime */\
|
||||||
|
(2 + 2 + 3 + 3 + 3 + 3 + 3) * 4)
|
||||||
#define CB_OP_RECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
|
#define CB_OP_RECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
|
||||||
|
|
||||||
#if defined(CONFIG_NFS_V4_1)
|
#if defined(CONFIG_NFS_V4_1)
|
||||||
@ -635,6 +636,13 @@ static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec64 *
|
|||||||
return 0;
|
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)
|
static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec64 *time)
|
||||||
{
|
{
|
||||||
if (!(bitmap[1] & FATTR4_WORD1_TIME_METADATA))
|
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);
|
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)
|
static __be32 encode_compound_hdr_res(struct xdr_stream *xdr, struct cb_compound_hdr_res *hdr)
|
||||||
{
|
{
|
||||||
__be32 status;
|
__be32 status;
|
||||||
@ -697,12 +723,21 @@ static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr,
|
|||||||
if (unlikely(status != 0))
|
if (unlikely(status != 0))
|
||||||
goto out;
|
goto out;
|
||||||
status = encode_attr_size(xdr, res->bitmap, res->size);
|
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))
|
if (unlikely(status != 0))
|
||||||
goto out;
|
goto out;
|
||||||
status = encode_attr_ctime(xdr, res->bitmap, &res->ctime);
|
status = encode_attr_ctime(xdr, res->bitmap, &res->ctime);
|
||||||
if (unlikely(status != 0))
|
if (unlikely(status != 0))
|
||||||
goto out;
|
goto out;
|
||||||
status = encode_attr_mtime(xdr, res->bitmap, &res->mtime);
|
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)));
|
*savep = htonl((unsigned int)((char *)xdr->p - (char *)(savep+1)));
|
||||||
out:
|
out:
|
||||||
return status;
|
return status;
|
||||||
|
Loading…
Reference in New Issue
Block a user