Commit | Line | Data |
---|---|---|
85e174ba RL |
1 | /* |
2 | * pNFS client data structures. | |
3 | * | |
4 | * Copyright (c) 2002 | |
5 | * The Regents of the University of Michigan | |
6 | * All Rights Reserved | |
7 | * | |
8 | * Dean Hildebrand <dhildebz@umich.edu> | |
9 | * | |
10 | * Permission is granted to use, copy, create derivative works, and | |
11 | * redistribute this software and such derivative works for any purpose, | |
12 | * so long as the name of the University of Michigan is not used in | |
13 | * any advertising or publicity pertaining to the use or distribution | |
14 | * of this software without specific, written prior authorization. If | |
15 | * the above copyright notice or any other identification of the | |
16 | * University of Michigan is included in any copy of any portion of | |
17 | * this software, then the disclaimer below must also be included. | |
18 | * | |
19 | * This software is provided as is, without representation or warranty | |
20 | * of any kind either express or implied, including without limitation | |
21 | * the implied warranties of merchantability, fitness for a particular | |
22 | * purpose, or noninfringement. The Regents of the University of | |
23 | * Michigan shall not be liable for any damages, including special, | |
24 | * indirect, incidental, or consequential damages, with respect to any | |
25 | * claim arising out of or in connection with the use of the software, | |
26 | * even if it has been or is hereafter advised of the possibility of | |
27 | * such damages. | |
28 | */ | |
29 | ||
30 | #ifndef FS_NFS_PNFS_H | |
31 | #define FS_NFS_PNFS_H | |
32 | ||
974cec8c AA |
33 | struct pnfs_layout_segment { |
34 | struct list_head fi_list; | |
b1f69b75 | 35 | struct pnfs_layout_range range; |
974cec8c AA |
36 | struct kref kref; |
37 | struct pnfs_layout_hdr *layout; | |
38 | }; | |
39 | ||
85e174ba RL |
40 | #ifdef CONFIG_NFS_V4_1 |
41 | ||
42 | #define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4" | |
43 | ||
e5e94017 BH |
44 | enum { |
45 | NFS_LAYOUT_RO_FAILED = 0, /* get ro layout failed stop trying */ | |
46 | NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */ | |
b1f69b75 | 47 | NFS_LAYOUT_STATEID_SET, /* have a valid layout stateid */ |
e5e94017 BH |
48 | }; |
49 | ||
85e174ba RL |
50 | /* Per-layout driver specific registration structure */ |
51 | struct pnfs_layoutdriver_type { | |
02c35fca FI |
52 | struct list_head pnfs_tblid; |
53 | const u32 id; | |
54 | const char *name; | |
55 | struct module *owner; | |
1c787096 TM |
56 | int (*set_layoutdriver) (struct nfs_server *); |
57 | int (*clear_layoutdriver) (struct nfs_server *); | |
b1f69b75 AA |
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); | |
85e174ba RL |
60 | }; |
61 | ||
e5e94017 BH |
62 | struct pnfs_layout_hdr { |
63 | unsigned long refcount; | |
974cec8c AA |
64 | struct list_head layouts; /* other client layouts */ |
65 | struct list_head segs; /* layout segments list */ | |
b1f69b75 AA |
66 | seqlock_t seqlock; /* Protects the stateid */ |
67 | nfs4_stateid stateid; | |
e5e94017 BH |
68 | unsigned long state; |
69 | struct inode *inode; | |
70 | }; | |
71 | ||
b1f69b75 AA |
72 | struct 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 | ||
89 | static inline u32 | |
90 | nfs4_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 | ||
103 | struct pnfs_deviceid_node { | |
104 | struct hlist_node de_node; | |
105 | struct nfs4_deviceid de_id; | |
106 | atomic_t de_ref; | |
107 | }; | |
108 | ||
109 | struct 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 | ||
116 | extern int pnfs_alloc_init_deviceid_cache(struct nfs_client *, | |
117 | void (*free_callback)(struct pnfs_deviceid_node *)); | |
118 | extern void pnfs_put_deviceid_cache(struct nfs_client *); | |
119 | extern struct pnfs_deviceid_node *pnfs_find_get_deviceid( | |
120 | struct pnfs_deviceid_cache *, | |
121 | struct nfs4_deviceid *); | |
122 | extern struct pnfs_deviceid_node *pnfs_add_deviceid( | |
123 | struct pnfs_deviceid_cache *, | |
124 | struct pnfs_deviceid_node *); | |
125 | extern void pnfs_put_deviceid(struct pnfs_deviceid_cache *c, | |
126 | struct pnfs_deviceid_node *devid); | |
127 | ||
02c35fca FI |
128 | extern int pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *); |
129 | extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *); | |
130 | ||
b1f69b75 AA |
131 | /* nfs4proc.c */ |
132 | extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, | |
133 | struct pnfs_device *dev); | |
134 | extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); | |
135 | ||
136 | /* pnfs.c */ | |
e5e94017 BH |
137 | struct pnfs_layout_segment * |
138 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, | |
139 | enum pnfs_iomode access_type); | |
85e174ba RL |
140 | void set_pnfs_layoutdriver(struct nfs_server *, u32 id); |
141 | void unset_pnfs_layoutdriver(struct nfs_server *); | |
b1f69b75 | 142 | int pnfs_layout_process(struct nfs4_layoutget *lgp); |
e5e94017 | 143 | void pnfs_destroy_layout(struct nfs_inode *); |
974cec8c | 144 | void pnfs_destroy_all_layouts(struct nfs_client *); |
b1f69b75 AA |
145 | void put_layout_hdr(struct inode *inode); |
146 | void pnfs_get_layout_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, | |
147 | struct nfs4_state *open_state); | |
e5e94017 BH |
148 | |
149 | ||
150 | static inline int lo_fail_bit(u32 iomode) | |
151 | { | |
152 | return iomode == IOMODE_RW ? | |
153 | NFS_LAYOUT_RW_FAILED : NFS_LAYOUT_RO_FAILED; | |
154 | } | |
155 | ||
156 | /* Return true if a layout driver is being used for this mountpoint */ | |
157 | static inline int pnfs_enabled_sb(struct nfs_server *nfss) | |
158 | { | |
159 | return nfss->pnfs_curr_ld != NULL; | |
160 | } | |
85e174ba RL |
161 | |
162 | #else /* CONFIG_NFS_V4_1 */ | |
163 | ||
974cec8c AA |
164 | static inline void pnfs_destroy_all_layouts(struct nfs_client *clp) |
165 | { | |
166 | } | |
167 | ||
e5e94017 BH |
168 | static inline void pnfs_destroy_layout(struct nfs_inode *nfsi) |
169 | { | |
170 | } | |
171 | ||
172 | static inline struct pnfs_layout_segment * | |
173 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, | |
174 | enum pnfs_iomode access_type) | |
175 | { | |
176 | return NULL; | |
177 | } | |
178 | ||
85e174ba RL |
179 | static inline void set_pnfs_layoutdriver(struct nfs_server *s, u32 id) |
180 | { | |
181 | } | |
182 | ||
183 | static inline void unset_pnfs_layoutdriver(struct nfs_server *s) | |
184 | { | |
185 | } | |
186 | ||
187 | #endif /* CONFIG_NFS_V4_1 */ | |
188 | ||
189 | #endif /* FS_NFS_PNFS_H */ |