pnfs: GETDEVICELIST
The block driver uses GETDEVICELIST Signed-off-by: Andy Adamson <andros@netapp.com> [pass struct nfs_server * to getdevicelist] [get machince creds for getdevicelist] [fix getdevicelist decode sizing] Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: Benny Halevy <bhalevy@tonian.com> Signed-off-by: Jim Rees <rees@umich.edu> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>hifive-unleashed-5.1
parent
3557c6c3be
commit
7f11d8d38d
|
@ -5834,6 +5834,54 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve the list of Data Server devices from the MDS.
|
||||||
|
*/
|
||||||
|
static int _nfs4_getdevicelist(struct nfs_server *server,
|
||||||
|
const struct nfs_fh *fh,
|
||||||
|
struct pnfs_devicelist *devlist)
|
||||||
|
{
|
||||||
|
struct nfs4_getdevicelist_args args = {
|
||||||
|
.fh = fh,
|
||||||
|
.layoutclass = server->pnfs_curr_ld->id,
|
||||||
|
};
|
||||||
|
struct nfs4_getdevicelist_res res = {
|
||||||
|
.devlist = devlist,
|
||||||
|
};
|
||||||
|
struct rpc_message msg = {
|
||||||
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETDEVICELIST],
|
||||||
|
.rpc_argp = &args,
|
||||||
|
.rpc_resp = &res,
|
||||||
|
};
|
||||||
|
int status;
|
||||||
|
|
||||||
|
dprintk("--> %s\n", __func__);
|
||||||
|
status = nfs4_call_sync(server->client, server, &msg, &args.seq_args,
|
||||||
|
&res.seq_res, 0);
|
||||||
|
dprintk("<-- %s status=%d\n", __func__, status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs4_proc_getdevicelist(struct nfs_server *server,
|
||||||
|
const struct nfs_fh *fh,
|
||||||
|
struct pnfs_devicelist *devlist)
|
||||||
|
{
|
||||||
|
struct nfs4_exception exception = { };
|
||||||
|
int err;
|
||||||
|
|
||||||
|
do {
|
||||||
|
err = nfs4_handle_exception(server,
|
||||||
|
_nfs4_getdevicelist(server, fh, devlist),
|
||||||
|
&exception);
|
||||||
|
} while (exception.retry);
|
||||||
|
|
||||||
|
dprintk("%s: err=%d, num_devs=%u\n", __func__,
|
||||||
|
err, devlist->num_devs);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(nfs4_proc_getdevicelist);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev)
|
_nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev)
|
||||||
{
|
{
|
||||||
|
|
131
fs/nfs/nfs4xdr.c
131
fs/nfs/nfs4xdr.c
|
@ -314,6 +314,17 @@ static int nfs4_stat_to_errno(int);
|
||||||
XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5)
|
XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5)
|
||||||
#define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4)
|
#define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4)
|
||||||
#define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4)
|
#define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4)
|
||||||
|
#define encode_getdevicelist_maxsz (op_encode_hdr_maxsz + 4 + \
|
||||||
|
encode_verifier_maxsz)
|
||||||
|
#define decode_getdevicelist_maxsz (op_decode_hdr_maxsz + \
|
||||||
|
2 /* nfs_cookie4 gdlr_cookie */ + \
|
||||||
|
decode_verifier_maxsz \
|
||||||
|
/* verifier4 gdlr_verifier */ + \
|
||||||
|
1 /* gdlr_deviceid_list count */ + \
|
||||||
|
XDR_QUADLEN(NFS4_PNFS_GETDEVLIST_MAXNUM * \
|
||||||
|
NFS4_DEVICEID4_SIZE) \
|
||||||
|
/* gdlr_deviceid_list */ + \
|
||||||
|
1 /* bool gdlr_eof */)
|
||||||
#define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 4 + \
|
#define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 4 + \
|
||||||
XDR_QUADLEN(NFS4_DEVICEID4_SIZE))
|
XDR_QUADLEN(NFS4_DEVICEID4_SIZE))
|
||||||
#define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + \
|
#define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + \
|
||||||
|
@ -748,6 +759,14 @@ static int nfs4_stat_to_errno(int);
|
||||||
#define NFS4_dec_reclaim_complete_sz (compound_decode_hdr_maxsz + \
|
#define NFS4_dec_reclaim_complete_sz (compound_decode_hdr_maxsz + \
|
||||||
decode_sequence_maxsz + \
|
decode_sequence_maxsz + \
|
||||||
decode_reclaim_complete_maxsz)
|
decode_reclaim_complete_maxsz)
|
||||||
|
#define NFS4_enc_getdevicelist_sz (compound_encode_hdr_maxsz + \
|
||||||
|
encode_sequence_maxsz + \
|
||||||
|
encode_putfh_maxsz + \
|
||||||
|
encode_getdevicelist_maxsz)
|
||||||
|
#define NFS4_dec_getdevicelist_sz (compound_decode_hdr_maxsz + \
|
||||||
|
decode_sequence_maxsz + \
|
||||||
|
decode_putfh_maxsz + \
|
||||||
|
decode_getdevicelist_maxsz)
|
||||||
#define NFS4_enc_getdeviceinfo_sz (compound_encode_hdr_maxsz + \
|
#define NFS4_enc_getdeviceinfo_sz (compound_encode_hdr_maxsz + \
|
||||||
encode_sequence_maxsz +\
|
encode_sequence_maxsz +\
|
||||||
encode_getdeviceinfo_maxsz)
|
encode_getdeviceinfo_maxsz)
|
||||||
|
@ -1854,6 +1873,26 @@ static void encode_sequence(struct xdr_stream *xdr,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NFS_V4_1
|
#ifdef CONFIG_NFS_V4_1
|
||||||
|
static void
|
||||||
|
encode_getdevicelist(struct xdr_stream *xdr,
|
||||||
|
const struct nfs4_getdevicelist_args *args,
|
||||||
|
struct compound_hdr *hdr)
|
||||||
|
{
|
||||||
|
__be32 *p;
|
||||||
|
nfs4_verifier dummy = {
|
||||||
|
.data = "dummmmmy",
|
||||||
|
};
|
||||||
|
|
||||||
|
p = reserve_space(xdr, 20);
|
||||||
|
*p++ = cpu_to_be32(OP_GETDEVICELIST);
|
||||||
|
*p++ = cpu_to_be32(args->layoutclass);
|
||||||
|
*p++ = cpu_to_be32(NFS4_PNFS_GETDEVLIST_MAXNUM);
|
||||||
|
xdr_encode_hyper(p, 0ULL); /* cookie */
|
||||||
|
encode_nfs4_verifier(xdr, &dummy);
|
||||||
|
hdr->nops++;
|
||||||
|
hdr->replen += decode_getdevicelist_maxsz;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
encode_getdeviceinfo(struct xdr_stream *xdr,
|
encode_getdeviceinfo(struct xdr_stream *xdr,
|
||||||
const struct nfs4_getdeviceinfo_args *args,
|
const struct nfs4_getdeviceinfo_args *args,
|
||||||
|
@ -2774,6 +2813,24 @@ static void nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req,
|
||||||
encode_nops(&hdr);
|
encode_nops(&hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encode GETDEVICELIST request
|
||||||
|
*/
|
||||||
|
static void nfs4_xdr_enc_getdevicelist(struct rpc_rqst *req,
|
||||||
|
struct xdr_stream *xdr,
|
||||||
|
struct nfs4_getdevicelist_args *args)
|
||||||
|
{
|
||||||
|
struct compound_hdr hdr = {
|
||||||
|
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
|
||||||
|
};
|
||||||
|
|
||||||
|
encode_compound_hdr(xdr, req, &hdr);
|
||||||
|
encode_sequence(xdr, &args->seq_args, &hdr);
|
||||||
|
encode_putfh(xdr, args->fh, &hdr);
|
||||||
|
encode_getdevicelist(xdr, args, &hdr);
|
||||||
|
encode_nops(&hdr);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encode GETDEVICEINFO request
|
* Encode GETDEVICEINFO request
|
||||||
*/
|
*/
|
||||||
|
@ -5268,6 +5325,53 @@ out_overflow:
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_NFS_V4_1)
|
#if defined(CONFIG_NFS_V4_1)
|
||||||
|
/*
|
||||||
|
* TODO: Need to handle case when EOF != true;
|
||||||
|
*/
|
||||||
|
static int decode_getdevicelist(struct xdr_stream *xdr,
|
||||||
|
struct pnfs_devicelist *res)
|
||||||
|
{
|
||||||
|
__be32 *p;
|
||||||
|
int status, i;
|
||||||
|
struct nfs_writeverf verftemp;
|
||||||
|
|
||||||
|
status = decode_op_hdr(xdr, OP_GETDEVICELIST);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
p = xdr_inline_decode(xdr, 8 + 8 + 4);
|
||||||
|
if (unlikely(!p))
|
||||||
|
goto out_overflow;
|
||||||
|
|
||||||
|
/* TODO: Skip cookie for now */
|
||||||
|
p += 2;
|
||||||
|
|
||||||
|
/* Read verifier */
|
||||||
|
p = xdr_decode_opaque_fixed(p, verftemp.verifier, 8);
|
||||||
|
|
||||||
|
res->num_devs = be32_to_cpup(p);
|
||||||
|
|
||||||
|
dprintk("%s: num_dev %d\n", __func__, res->num_devs);
|
||||||
|
|
||||||
|
if (res->num_devs > NFS4_PNFS_GETDEVLIST_MAXNUM) {
|
||||||
|
printk(KERN_ERR "%s too many result dev_num %u\n",
|
||||||
|
__func__, res->num_devs);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = xdr_inline_decode(xdr,
|
||||||
|
res->num_devs * NFS4_DEVICEID4_SIZE + 4);
|
||||||
|
if (unlikely(!p))
|
||||||
|
goto out_overflow;
|
||||||
|
for (i = 0; i < res->num_devs; i++)
|
||||||
|
p = xdr_decode_opaque_fixed(p, res->dev_id[i].data,
|
||||||
|
NFS4_DEVICEID4_SIZE);
|
||||||
|
res->eof = be32_to_cpup(p);
|
||||||
|
return 0;
|
||||||
|
out_overflow:
|
||||||
|
print_overflow_msg(__func__, xdr);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
static int decode_getdeviceinfo(struct xdr_stream *xdr,
|
static int decode_getdeviceinfo(struct xdr_stream *xdr,
|
||||||
struct pnfs_device *pdev)
|
struct pnfs_device *pdev)
|
||||||
|
@ -6541,6 +6645,32 @@ static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode GETDEVICELIST response
|
||||||
|
*/
|
||||||
|
static int nfs4_xdr_dec_getdevicelist(struct rpc_rqst *rqstp,
|
||||||
|
struct xdr_stream *xdr,
|
||||||
|
struct nfs4_getdevicelist_res *res)
|
||||||
|
{
|
||||||
|
struct compound_hdr hdr;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
dprintk("encoding getdevicelist!\n");
|
||||||
|
|
||||||
|
status = decode_compound_hdr(xdr, &hdr);
|
||||||
|
if (status != 0)
|
||||||
|
goto out;
|
||||||
|
status = decode_sequence(xdr, &res->seq_res, rqstp);
|
||||||
|
if (status != 0)
|
||||||
|
goto out;
|
||||||
|
status = decode_putfh(xdr);
|
||||||
|
if (status != 0)
|
||||||
|
goto out;
|
||||||
|
status = decode_getdevicelist(xdr, res->devlist);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decode GETDEVINFO response
|
* Decode GETDEVINFO response
|
||||||
*/
|
*/
|
||||||
|
@ -6908,6 +7038,7 @@ struct rpc_procinfo nfs4_procedures[] = {
|
||||||
PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name),
|
PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name),
|
||||||
PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid),
|
PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid),
|
||||||
PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid),
|
PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid),
|
||||||
|
PROC(GETDEVICELIST, enc_getdevicelist, dec_getdevicelist),
|
||||||
#endif /* CONFIG_NFS_V4_1 */
|
#endif /* CONFIG_NFS_V4_1 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -135,14 +135,26 @@ struct pnfs_device {
|
||||||
unsigned int layout_type;
|
unsigned int layout_type;
|
||||||
unsigned int mincount;
|
unsigned int mincount;
|
||||||
struct page **pages;
|
struct page **pages;
|
||||||
|
void *area;
|
||||||
unsigned int pgbase;
|
unsigned int pgbase;
|
||||||
unsigned int pglen;
|
unsigned int pglen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define NFS4_PNFS_GETDEVLIST_MAXNUM 16
|
||||||
|
|
||||||
|
struct pnfs_devicelist {
|
||||||
|
unsigned int eof;
|
||||||
|
unsigned int num_devs;
|
||||||
|
struct nfs4_deviceid dev_id[NFS4_PNFS_GETDEVLIST_MAXNUM];
|
||||||
|
};
|
||||||
|
|
||||||
extern int pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *);
|
extern int pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *);
|
||||||
extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *);
|
extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *);
|
||||||
|
|
||||||
/* nfs4proc.c */
|
/* nfs4proc.c */
|
||||||
|
extern int nfs4_proc_getdevicelist(struct nfs_server *server,
|
||||||
|
const struct nfs_fh *fh,
|
||||||
|
struct pnfs_devicelist *devlist);
|
||||||
extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
|
extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
|
||||||
struct pnfs_device *dev);
|
struct pnfs_device *dev);
|
||||||
extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp);
|
extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp);
|
||||||
|
|
|
@ -566,6 +566,7 @@ enum {
|
||||||
NFSPROC4_CLNT_SECINFO_NO_NAME,
|
NFSPROC4_CLNT_SECINFO_NO_NAME,
|
||||||
NFSPROC4_CLNT_TEST_STATEID,
|
NFSPROC4_CLNT_TEST_STATEID,
|
||||||
NFSPROC4_CLNT_FREE_STATEID,
|
NFSPROC4_CLNT_FREE_STATEID,
|
||||||
|
NFSPROC4_CLNT_GETDEVICELIST,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* nfs41 types */
|
/* nfs41 types */
|
||||||
|
|
|
@ -235,6 +235,17 @@ struct nfs4_layoutget {
|
||||||
gfp_t gfp_flags;
|
gfp_t gfp_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct nfs4_getdevicelist_args {
|
||||||
|
const struct nfs_fh *fh;
|
||||||
|
u32 layoutclass;
|
||||||
|
struct nfs4_sequence_args seq_args;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nfs4_getdevicelist_res {
|
||||||
|
struct pnfs_devicelist *devlist;
|
||||||
|
struct nfs4_sequence_res seq_res;
|
||||||
|
};
|
||||||
|
|
||||||
struct nfs4_getdeviceinfo_args {
|
struct nfs4_getdeviceinfo_args {
|
||||||
struct pnfs_device *pdev;
|
struct pnfs_device *pdev;
|
||||||
struct nfs4_sequence_args seq_args;
|
struct nfs4_sequence_args seq_args;
|
||||||
|
|
Loading…
Reference in New Issue