[pnfs] [PATCH 09/23] 2.6-latest pnfs client getdeviceinfo
andros at umich.edu
andros at umich.edu
Thu Dec 13 15:51:35 EST 2007
From: Andy Adamson <andros at umich.edu>
The getdeviceinfo call is made by the client when a layoutget operation
returns an unknown device id.
Use the filehandle of the layoutget call as the current filehandle
for the getdeviceinfo call, instead of the filehandle of the pNFS mount point.
The 2.6.18.3 getdeviceinfo call used the root filehandle of the mount point
stored in struct nfs_server->fh. The 2.6.24 nfs client no longer saves the
root filehandle. Instead, a local variable is used.
There is no reason to use the MDS mountpoint filehandle for getdeviceinfo.
Instead of reverting the 2.6.24 code to save the filehandle of the pNFS
mount point, this patch uses the filehandle of the layoutget call that
initiated the getdeviceinfo call.
Change the interface of nfs4filelayoutdev.c:get_device_info, replacing the
struct filelayout_mount_point pointer to a struct inode pointer.
The inode pointer is used to get the filehandle for the getdeviceinfo call.
Declare a macro to dereference the struct filelayout_mount_type given an
inode.
Signed-off by: Andy Adamson<andros at umich.edu>
---
fs/nfs/nfs4filelayout.c | 2 +-
fs/nfs/nfs4filelayout.h | 7 ++-
fs/nfs/nfs4filelayoutdev.c | 39 +++++------------
fs/nfs/nfs4proc.c | 28 ++++++++++--
fs/nfs/nfs4xdr.c | 100 ++++++++++++++++++++++++++++++++++++++++++++
fs/nfs/pnfs.c | 7 +--
include/linux/nfs4_pnfs.h | 2 +-
7 files changed, 144 insertions(+), 41 deletions(-)
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index c3db428..93ba961 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -540,7 +540,7 @@ filelayout_commit(struct pnfs_layout_type * layoutid, struct inode* ino, struct
nfs_execute_write(data);
return 0;
}
- dev = nfs4_pnfs_device_item_get(layoutid, nfslay->dev_id);
+ dev = nfs4_pnfs_device_item_get(ino, nfslay->dev_id);
fdev = &dev->stripe_devs[0];
for (i = 0; i < nfslay->num_fh; i++) {
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
index d181473..b5e6c2f 100644
--- a/fs/nfs/nfs4filelayout.h
+++ b/fs/nfs/nfs4filelayout.h
@@ -21,6 +21,9 @@
#define NFS4_PNFS_MAX_STRIPE_CNT 16
#define NFS4_PNFS_MAX_MULTI_DS 2
+
+#define FILE_MT(inode) ((struct filelayout_mount_type *)(NFS_SERVER(inode)->pnfs_mountid->mountid))
+
struct nfs4_session *nfs41_alloc_session(void);
int _nfs4_proc_create_session(struct nfs_client *clp, struct nfs4_session *session,
struct rpc_clnt *clnt);
@@ -105,10 +108,8 @@ int nfs4_pnfs_dserver_get(struct inode *inode,
struct nfs4_pnfs_dserver *dserver);
int decode_and_add_devicelist(struct filelayout_mount_type *mt, struct pnfs_devicelist* devlist);
-struct nfs4_pnfs_dev *
-nfs4_pnfs_device_get(struct inode *inode, u32 dev_id, u32 stripe_index);
struct nfs4_pnfs_dev_item *
-nfs4_pnfs_device_item_get(struct pnfs_layout_type *ltype, u32 dev_id);
+nfs4_pnfs_device_item_get(struct inode *inode, u32 dev_id);
#define READ32(x) (x) = ntohl(*p++)
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index e761546..b175fb9 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -598,18 +598,21 @@ decode_and_add_devicelist(struct filelayout_mount_type *mt, struct pnfs_deviceli
* of available devices, and return it.
*/
static struct nfs4_pnfs_dev_item *
-get_device_info(struct filelayout_mount_type *mt, u32 dev_id)
+get_device_info(struct inode *inode, u32 dev_id)
{
- int rc;
+ struct filelayout_mount_type *mt = FILE_MT(inode);
struct pnfs_device *pdev = NULL;
+ int rc;
+ dprintk("%s mt %p\n", __func__, mt);
if ((pdev = kmalloc(sizeof(struct pnfs_device), GFP_KERNEL)) == NULL) {
return NULL;
}
pdev->dev_id = dev_id;
- rc = pnfs_callback_ops->nfs_getdeviceinfo(mt->fl_sb, dev_id, pdev);
+ rc = pnfs_callback_ops->nfs_getdeviceinfo(inode, dev_id, pdev);
+ dprintk("%s getdevice info returns %d\n", __func__, rc);
if (rc) {
kfree(pdev);
return NULL;
@@ -622,42 +625,20 @@ get_device_info(struct filelayout_mount_type *mt, u32 dev_id)
}
struct nfs4_pnfs_dev_item *
-nfs4_pnfs_device_item_get(struct pnfs_layout_type *ltype, u32 dev_id)
+nfs4_pnfs_device_item_get(struct inode *inode, u32 dev_id)
{
- struct filelayout_mount_type *mt;
+ struct filelayout_mount_type *mt = FILE_MT(inode);
struct nfs4_pnfs_dev_item *dev;
- mt = (struct filelayout_mount_type *)ltype->mountid->mountid;
-
read_lock(&mt->hlist->dev_lock);
dev = _device_lookup(mt->hlist, dev_id);
read_unlock(&mt->hlist->dev_lock);
if (dev == NULL)
- dev = get_device_info(mt, dev_id);
+ dev = get_device_info(inode, dev_id);
return dev;
}
-/* Lookup and return the data server struct
- */
-struct nfs4_pnfs_dev *
-nfs4_pnfs_device_get(struct inode *inode, u32 dev_id, u32 stripe_idx)
-{
- struct nfs4_pnfs_dev_item *dev;
- struct nfs_server* server = NFS_SERVER(inode);
- struct filelayout_mount_type *mt;
-
- mt = (struct filelayout_mount_type*)server->pnfs_mountid->mountid;
-
- read_lock(&mt->hlist->dev_lock);
- dev = _device_lookup(mt->hlist, dev_id);
- read_unlock(&mt->hlist->dev_lock);
- if (dev == NULL)
- dev = get_device_info(mt, dev_id);
-
- return &dev->stripe_devs[stripe_idx];
-}
-
/* Retrieve the rpc client for a specified byte range
* in 'inode' by filling in the contents of 'dserver'.
*/
@@ -692,9 +673,11 @@ nfs4_pnfs_dserver_get(struct inode *inode,
BUG_ON(dbg_stripe_idx != stripe_idx);
+ /* TODO: rewrite this function!
dserver->dev = nfs4_pnfs_device_get(inode, layout->dev_id, stripe_idx);
if (dserver->dev == NULL)
return 1;
+ */
dserver->fh = &layout->fh_array[stripe_idx];
dprintk("%s: dev_id=%u, idx=%u, offset=%Lu, count=%u\n",
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f78d4ef..d446721 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5029,12 +5029,32 @@ int nfs4_pnfs_getdevicelist(struct nfs_fh *fh,
return err;
}
-int nfs4_pnfs_getdeviceinfo(struct nfs_server *server,
+int nfs4_pnfs_getdeviceinfo(struct inode *inode,
u32 dev_id,
- struct pnfs_device* res)
+ struct pnfs_device* dev)
{
- /* XXX Need to implement */
- return -1;
+ struct nfs_server *server = NFS_SERVER(inode);
+ struct nfs4_pnfs_getdeviceinfo_arg args = {
+ .fh = NFS_FH(inode),
+ .dev_id = dev_id,
+ .layoutclass = server->pnfs_curr_ld->id,
+ };
+ struct nfs4_pnfs_getdeviceinfo_res res = {
+ .dev = dev,
+ };
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_PNFS_GETDEVICEINFO],
+ .rpc_argp = &args,
+ .rpc_resp = &res,
+ };
+
+ int status = -ENOMEM;
+
+ NFS4_VALIDATE_STATE(server);
+ status = NFS4_RPC_CALL_SYNC(server, server->client, &msg, &args,
+ &res, 0);
+
+ return status;
}
#endif /* CONFIG_PNFS */
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 74963db..556ac0a 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -274,6 +274,9 @@ static int nr_sequence_quads = 0;
(NFS4_VERIFIER_SIZE >> 2))
#define decode_getdevicelist_maxsz (op_decode_hdr_maxsz + 5 + 2 + \
NFS4_PNFS_DEV_MAXCOUNT*NFS4_PNFS_DEV_MAXSIZE)
+#define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 2)
+#define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + 3 + \
+ NFS4_PNFS_DEV_MAXSIZE)
#define encode_pnfs_layoutget_sz (op_encode_hdr_maxsz + 13)
#define decode_pnfs_layoutget_maxsz (op_decode_hdr_maxsz + 8)
#endif /* CONFIG_PNFS */
@@ -723,6 +726,14 @@ static int nr_sequence_quads = 0;
decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_getdevicelist_maxsz)
+#define NFS41_enc_pnfs_getdeviceinfo_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz +\
+ encode_putfh_maxsz + \
+ encode_getdeviceinfo_maxsz)
+#define NFS41_dec_pnfs_getdeviceinfo_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
+ decode_putfh_maxsz + \
+ decode_getdeviceinfo_maxsz)
#define NFS41_enc_pnfs_layoutget_sz (compound_encode_hdr_maxsz + \
encode_sequence_maxsz +\
encode_putfh_maxsz + \
@@ -1728,6 +1739,20 @@ static int encode_getdevicelist(struct xdr_stream *xdr, const struct nfs4_pnfs_g
}
/*
+ * Encode request to get information for a specific device.
+ */
+static int encode_getdeviceinfo(struct xdr_stream *xdr, const struct nfs4_pnfs_getdeviceinfo_arg *args)
+{
+ uint32_t *p;
+ RESERVE_SPACE(16);
+ WRITE32(OP_GETDEVICEINFO);
+ WRITE32(args->dev_id);
+ WRITE32(args->layoutclass);
+ WRITE32(NFS4_PNFS_DEV_MAXSIZE);
+ return 0;
+}
+
+/*
* Encode request to get pNFS layout. Sent to the MDS
*/
static int encode_pnfs_layoutget(struct xdr_stream *xdr, const struct nfs4_pnfs_layoutget_arg *args)
@@ -3369,6 +3394,30 @@ out:
}
/*
+ * Encode GETDEVICEINFO request
+ */
+static int nfs41_xdr_enc_pnfs_getdeviceinfo(struct rpc_rqst *req,
+uint32_t *p,
+struct nfs4_pnfs_getdeviceinfo_arg *args)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr = {
+ .nops = 3,
+ };
+ int status;
+
+ xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+ encode_compound_hdr(&xdr, &hdr, 1);
+ encode_sequence(&xdr, &args->seq_args);
+ status = encode_putfh(&xdr, args->fh);
+ if (status != 0)
+ goto out;
+ status = encode_getdeviceinfo(&xdr, args);
+out:
+ return status;
+}
+
+/*
* Encode LAYOUTGET request
*/
static int nfs41_xdr_enc_pnfs_layoutget(struct rpc_rqst *req, uint32_t *p, struct nfs4_pnfs_layoutget_arg *args)
@@ -5228,6 +5277,32 @@ static int decode_getdevicelist(struct xdr_stream *xdr, struct pnfs_devicelist *
}
/*
+ * Decode GETDEVICEINFO reply
+ */
+static int decode_getdeviceinfo(struct xdr_stream *xdr,
+struct pnfs_device *res)
+{
+ uint32_t *p;
+ uint32_t len, type;
+ int status;
+
+ status = decode_op_hdr(xdr, OP_GETDEVICEINFO);
+ if (status)
+ return status;
+
+ READ_BUF(4); /* TODO: confirm layout type */
+ READ32(type);
+ READ_BUF(4);
+ READ32(len);
+ READ_BUF(len);
+
+ COPYMEM(&res->dev_addr_buf, len);
+ res->dev_addr_len = len;
+
+ return 0;
+}
+
+/*
* Decode LAYOUT_GET reply
*/
static int decode_pnfs_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_pnfs_layoutget_res *res)
@@ -7094,6 +7169,30 @@ out:
}
/*
+ * Decode GETDEVINFO response
+ */
+static int nfs41_xdr_dec_pnfs_getdeviceinfo(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_pnfs_getdeviceinfo_res *res)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr;
+ int status;
+
+ xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status != 0)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res);
+ if (status != 0)
+ goto out;
+ status = decode_putfh(&xdr);
+ if (status != 0)
+ goto out;
+ status = decode_getdeviceinfo(&xdr, res->dev);
+out:
+ return status;
+}
+
+/*
* Decode LAYOUTGET response
*/
static int nfs41_xdr_dec_pnfs_layoutget(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_pnfs_layoutget_res *res)
@@ -7332,6 +7431,7 @@ struct rpc_procinfo nfs41_procedures[] = {
PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time, 1),
#if defined (CONFIG_PNFS)
PROC(PNFS_GETDEVICELIST, enc_pnfs_getdevicelist, dec_pnfs_getdevicelist, 1),
+ PROC(PNFS_GETDEVICEINFO, enc_pnfs_getdeviceinfo, dec_pnfs_getdeviceinfo, 1),
PROC(PNFS_LAYOUTGET, enc_pnfs_layoutget, dec_pnfs_layoutget, 1),
#endif /* CONFIG_PNFS */
};
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index d411c45..3f765ad 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -57,7 +57,7 @@
extern int nfs_fsync(struct file *file, struct dentry *dentry, int datasync);
extern int nfs4_pnfs_getdevicelist(struct nfs_fh *fh, struct nfs_server *server,
struct pnfs_devicelist* devlist);
-extern int nfs4_pnfs_getdeviceinfo(struct nfs_server *server, u32 dev_id,
+extern int nfs4_pnfs_getdeviceinfo(struct inode *inode, u32 dev_id,
struct pnfs_device *res);
extern void nfs_execute_write(struct nfs_write_data *data);
extern void nfs_commit_rpcsetup(struct nfs_write_data *data, int sync);
@@ -1273,12 +1273,11 @@ pnfs_getdevicelist(struct super_block *sb, struct nfs_fh *fh, struct pnfs_device
/* Retrieve the device information for a device.
*/
int
-pnfs_getdeviceinfo(struct super_block *sb, u32 dev_id, struct pnfs_device* dev)
+pnfs_getdeviceinfo(struct inode *inode, u32 dev_id, struct pnfs_device* dev)
{
- struct nfs_server *server = NFS_SB(sb);
int rc;
- rc = nfs4_pnfs_getdeviceinfo(server, dev_id, dev);
+ rc = nfs4_pnfs_getdeviceinfo(inode, dev_id, dev);
return rc;
}
diff --git a/include/linux/nfs4_pnfs.h b/include/linux/nfs4_pnfs.h
index b59ee2b..67bc533 100644
--- a/include/linux/nfs4_pnfs.h
+++ b/include/linux/nfs4_pnfs.h
@@ -144,7 +144,7 @@ struct pnfs_devicelist {
struct pnfs_client_operations {
int (*nfs_fsync) (struct file * file, struct dentry * dentry, int datasync);
int (*nfs_getdevicelist) (struct super_block * sb, struct nfs_fh *fh, struct pnfs_devicelist* devlist);
- int (*nfs_getdeviceinfo) (struct super_block * sb, u32 dev_id, struct pnfs_device * dev);
+ int (*nfs_getdeviceinfo) (struct inode * inode, u32 dev_id, struct pnfs_device * dev);
/* Post read callback. Layout driver calls this function if unstable data was
* written and requires a commit call
--
1.5.0.2
More information about the pNFS
mailing list