aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pnfs.h
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2010-10-20 00:18:03 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-10-24 18:07:10 -0400
commitb1f69b754ee312ec75f2c7ead0e6851cd9598cc2 (patch)
tree1d8e70abb2cd087e3b97f73d86db8b9568467378 /fs/nfs/pnfs.h
parent974cec8ca0352eb5d281535b714cf194a606e98f (diff)
NFSv4.1: pnfs: add LAYOUTGET and GETDEVICEINFO infrastructure
Add the ability to actually send LAYOUTGET and GETDEVICEINFO. This also adds in the machinery to handle layout state and the deviceid cache. Note that GETDEVICEINFO is not called directly by the generic layer. Instead it is called by the drivers while parsing the LAYOUTGET opaque data in response to an unknown device id embedded therein. RFC 5661 only encodes device ids within the driver-specific opaque data. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Dean Hildebrand <dhildebz@umich.edu> Signed-off-by: Marc Eshel <eshel@almaden.ibm.com> Signed-off-by: Mike Sager <sager@netapp.com> Signed-off-by: Ricardo Labiaga <ricardo.labiaga@netapp.com> Signed-off-by: Tao Guo <guotao@nrchpc.ac.cn> Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/pnfs.h')
-rw-r--r--fs/nfs/pnfs.h73
1 files changed, 72 insertions, 1 deletions
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 1c3eb02f4944..cbba28cb02a7 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -32,7 +32,7 @@
32 32
33struct pnfs_layout_segment { 33struct pnfs_layout_segment {
34 struct list_head fi_list; 34 struct list_head fi_list;
35 u32 iomode; 35 struct pnfs_layout_range range;
36 struct kref kref; 36 struct kref kref;
37 struct pnfs_layout_hdr *layout; 37 struct pnfs_layout_hdr *layout;
38}; 38};
@@ -44,6 +44,7 @@ struct pnfs_layout_segment {
44enum { 44enum {
45 NFS_LAYOUT_RO_FAILED = 0, /* get ro layout failed stop trying */ 45 NFS_LAYOUT_RO_FAILED = 0, /* get ro layout failed stop trying */
46 NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */ 46 NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */
47 NFS_LAYOUT_STATEID_SET, /* have a valid layout stateid */
47}; 48};
48 49
49/* Per-layout driver specific registration structure */ 50/* Per-layout driver specific registration structure */
@@ -54,26 +55,96 @@ struct pnfs_layoutdriver_type {
54 struct module *owner; 55 struct module *owner;
55 int (*initialize_mountpoint) (struct nfs_server *); 56 int (*initialize_mountpoint) (struct nfs_server *);
56 int (*uninitialize_mountpoint) (struct nfs_server *); 57 int (*uninitialize_mountpoint) (struct nfs_server *);
58 struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr);
59 void (*free_lseg) (struct pnfs_layout_segment *lseg);
57}; 60};
58 61
59struct pnfs_layout_hdr { 62struct pnfs_layout_hdr {
60 unsigned long refcount; 63 unsigned long refcount;
61 struct list_head layouts; /* other client layouts */ 64 struct list_head layouts; /* other client layouts */
62 struct list_head segs; /* layout segments list */ 65 struct list_head segs; /* layout segments list */
66 seqlock_t seqlock; /* Protects the stateid */
67 nfs4_stateid stateid;
63 unsigned long state; 68 unsigned long state;
64 struct inode *inode; 69 struct inode *inode;
65}; 70};
66 71
72struct pnfs_device {
73 struct nfs4_deviceid dev_id;
74 unsigned int layout_type;
75 unsigned int mincount;
76 struct page **pages;
77 void *area;
78 unsigned int pgbase;
79 unsigned int pglen;
80};
81
82/*
83 * Device ID RCU cache. A device ID is unique per client ID and layout type.
84 */
85#define NFS4_DEVICE_ID_HASH_BITS 5
86#define NFS4_DEVICE_ID_HASH_SIZE (1 << NFS4_DEVICE_ID_HASH_BITS)
87#define NFS4_DEVICE_ID_HASH_MASK (NFS4_DEVICE_ID_HASH_SIZE - 1)
88
89static inline u32
90nfs4_deviceid_hash(struct nfs4_deviceid *id)
91{
92 unsigned char *cptr = (unsigned char *)id->data;
93 unsigned int nbytes = NFS4_DEVICEID4_SIZE;
94 u32 x = 0;
95
96 while (nbytes--) {
97 x *= 37;
98 x += *cptr++;
99 }
100 return x & NFS4_DEVICE_ID_HASH_MASK;
101}
102
103struct pnfs_deviceid_node {
104 struct hlist_node de_node;
105 struct nfs4_deviceid de_id;
106 atomic_t de_ref;
107};
108
109struct pnfs_deviceid_cache {
110 spinlock_t dc_lock;
111 atomic_t dc_ref;
112 void (*dc_free_callback)(struct pnfs_deviceid_node *);
113 struct hlist_head dc_deviceids[NFS4_DEVICE_ID_HASH_SIZE];
114};
115
116extern int pnfs_alloc_init_deviceid_cache(struct nfs_client *,
117 void (*free_callback)(struct pnfs_deviceid_node *));
118extern void pnfs_put_deviceid_cache(struct nfs_client *);
119extern struct pnfs_deviceid_node *pnfs_find_get_deviceid(
120 struct pnfs_deviceid_cache *,
121 struct nfs4_deviceid *);
122extern struct pnfs_deviceid_node *pnfs_add_deviceid(
123 struct pnfs_deviceid_cache *,
124 struct pnfs_deviceid_node *);
125extern void pnfs_put_deviceid(struct pnfs_deviceid_cache *c,
126 struct pnfs_deviceid_node *devid);
127
67extern int pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *); 128extern int pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *);
68extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *); 129extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *);
69 130
131/* nfs4proc.c */
132extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
133 struct pnfs_device *dev);
134extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp);
135
136/* pnfs.c */
70struct pnfs_layout_segment * 137struct pnfs_layout_segment *
71pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, 138pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx,
72 enum pnfs_iomode access_type); 139 enum pnfs_iomode access_type);
73void set_pnfs_layoutdriver(struct nfs_server *, u32 id); 140void set_pnfs_layoutdriver(struct nfs_server *, u32 id);
74void unset_pnfs_layoutdriver(struct nfs_server *); 141void unset_pnfs_layoutdriver(struct nfs_server *);
142int pnfs_layout_process(struct nfs4_layoutget *lgp);
75void pnfs_destroy_layout(struct nfs_inode *); 143void pnfs_destroy_layout(struct nfs_inode *);
76void pnfs_destroy_all_layouts(struct nfs_client *); 144void pnfs_destroy_all_layouts(struct nfs_client *);
145void put_layout_hdr(struct inode *inode);
146void pnfs_get_layout_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo,
147 struct nfs4_state *open_state);
77 148
78 149
79static inline int lo_fail_bit(u32 iomode) 150static inline int lo_fail_bit(u32 iomode)