]>
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 | ||
4541d16c FI |
33 | enum { |
34 | NFS_LSEG_VALID = 0, /* cleared when lseg is recalled/returned */ | |
35 | }; | |
36 | ||
974cec8c | 37 | struct pnfs_layout_segment { |
566052c5 FI |
38 | struct list_head pls_list; |
39 | struct pnfs_layout_range pls_range; | |
4541d16c FI |
40 | atomic_t pls_refcount; |
41 | unsigned long pls_flags; | |
566052c5 | 42 | struct pnfs_layout_hdr *pls_layout; |
974cec8c AA |
43 | }; |
44 | ||
85e174ba RL |
45 | #ifdef CONFIG_NFS_V4_1 |
46 | ||
47 | #define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4" | |
48 | ||
e5e94017 BH |
49 | enum { |
50 | NFS_LAYOUT_RO_FAILED = 0, /* get ro layout failed stop trying */ | |
51 | NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */ | |
43f1b3da | 52 | NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */ |
4541d16c | 53 | NFS_LAYOUT_DESTROYED, /* no new use of layout allowed */ |
e5e94017 BH |
54 | }; |
55 | ||
85e174ba RL |
56 | /* Per-layout driver specific registration structure */ |
57 | struct pnfs_layoutdriver_type { | |
02c35fca FI |
58 | struct list_head pnfs_tblid; |
59 | const u32 id; | |
60 | const char *name; | |
61 | struct module *owner; | |
1c787096 TM |
62 | int (*set_layoutdriver) (struct nfs_server *); |
63 | int (*clear_layoutdriver) (struct nfs_server *); | |
b1f69b75 AA |
64 | struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr); |
65 | void (*free_lseg) (struct pnfs_layout_segment *lseg); | |
85e174ba RL |
66 | }; |
67 | ||
e5e94017 | 68 | struct pnfs_layout_hdr { |
cc6e5340 | 69 | atomic_t plh_refcount; |
b7edfaa1 | 70 | struct list_head plh_layouts; /* other client layouts */ |
43f1b3da | 71 | struct list_head plh_bulk_recall; /* clnt list of bulk recalls */ |
b7edfaa1 | 72 | struct list_head plh_segs; /* layout segments list */ |
b7edfaa1 | 73 | nfs4_stateid plh_stateid; |
cf7d63f1 | 74 | atomic_t plh_outstanding; /* number of RPCs out */ |
43f1b3da | 75 | u32 plh_barrier; /* ignore lower seqids */ |
566052c5 | 76 | unsigned long plh_flags; |
b7edfaa1 | 77 | struct inode *plh_inode; |
e5e94017 BH |
78 | }; |
79 | ||
b1f69b75 AA |
80 | struct pnfs_device { |
81 | struct nfs4_deviceid dev_id; | |
82 | unsigned int layout_type; | |
83 | unsigned int mincount; | |
84 | struct page **pages; | |
85 | void *area; | |
86 | unsigned int pgbase; | |
87 | unsigned int pglen; | |
88 | }; | |
89 | ||
90 | /* | |
91 | * Device ID RCU cache. A device ID is unique per client ID and layout type. | |
92 | */ | |
93 | #define NFS4_DEVICE_ID_HASH_BITS 5 | |
94 | #define NFS4_DEVICE_ID_HASH_SIZE (1 << NFS4_DEVICE_ID_HASH_BITS) | |
95 | #define NFS4_DEVICE_ID_HASH_MASK (NFS4_DEVICE_ID_HASH_SIZE - 1) | |
96 | ||
97 | static inline u32 | |
98 | nfs4_deviceid_hash(struct nfs4_deviceid *id) | |
99 | { | |
100 | unsigned char *cptr = (unsigned char *)id->data; | |
101 | unsigned int nbytes = NFS4_DEVICEID4_SIZE; | |
102 | u32 x = 0; | |
103 | ||
104 | while (nbytes--) { | |
105 | x *= 37; | |
106 | x += *cptr++; | |
107 | } | |
108 | return x & NFS4_DEVICE_ID_HASH_MASK; | |
109 | } | |
110 | ||
111 | struct pnfs_deviceid_node { | |
112 | struct hlist_node de_node; | |
113 | struct nfs4_deviceid de_id; | |
114 | atomic_t de_ref; | |
115 | }; | |
116 | ||
117 | struct pnfs_deviceid_cache { | |
118 | spinlock_t dc_lock; | |
119 | atomic_t dc_ref; | |
120 | void (*dc_free_callback)(struct pnfs_deviceid_node *); | |
121 | struct hlist_head dc_deviceids[NFS4_DEVICE_ID_HASH_SIZE]; | |
122 | }; | |
123 | ||
124 | extern int pnfs_alloc_init_deviceid_cache(struct nfs_client *, | |
125 | void (*free_callback)(struct pnfs_deviceid_node *)); | |
126 | extern void pnfs_put_deviceid_cache(struct nfs_client *); | |
127 | extern struct pnfs_deviceid_node *pnfs_find_get_deviceid( | |
128 | struct pnfs_deviceid_cache *, | |
129 | struct nfs4_deviceid *); | |
130 | extern struct pnfs_deviceid_node *pnfs_add_deviceid( | |
131 | struct pnfs_deviceid_cache *, | |
132 | struct pnfs_deviceid_node *); | |
133 | extern void pnfs_put_deviceid(struct pnfs_deviceid_cache *c, | |
134 | struct pnfs_deviceid_node *devid); | |
135 | ||
02c35fca FI |
136 | extern int pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *); |
137 | extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *); | |
138 | ||
b1f69b75 AA |
139 | /* nfs4proc.c */ |
140 | extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, | |
141 | struct pnfs_device *dev); | |
142 | extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); | |
143 | ||
144 | /* pnfs.c */ | |
43f1b3da | 145 | void get_layout_hdr(struct pnfs_layout_hdr *lo); |
e5e94017 BH |
146 | struct pnfs_layout_segment * |
147 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, | |
148 | enum pnfs_iomode access_type); | |
85e174ba RL |
149 | void set_pnfs_layoutdriver(struct nfs_server *, u32 id); |
150 | void unset_pnfs_layoutdriver(struct nfs_server *); | |
b1f69b75 | 151 | int pnfs_layout_process(struct nfs4_layoutget *lgp); |
43f1b3da | 152 | void pnfs_free_lseg_list(struct list_head *tmp_list); |
e5e94017 | 153 | void pnfs_destroy_layout(struct nfs_inode *); |
974cec8c | 154 | void pnfs_destroy_all_layouts(struct nfs_client *); |
cc6e5340 | 155 | void put_layout_hdr(struct pnfs_layout_hdr *lo); |
43f1b3da FI |
156 | void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, |
157 | const nfs4_stateid *new, | |
158 | bool update_barrier); | |
fd6002e9 FI |
159 | int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, |
160 | struct pnfs_layout_hdr *lo, | |
161 | struct nfs4_state *open_state); | |
43f1b3da FI |
162 | int mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, |
163 | struct list_head *tmp_list, | |
164 | u32 iomode); | |
e5e94017 BH |
165 | |
166 | ||
167 | static inline int lo_fail_bit(u32 iomode) | |
168 | { | |
169 | return iomode == IOMODE_RW ? | |
170 | NFS_LAYOUT_RW_FAILED : NFS_LAYOUT_RO_FAILED; | |
171 | } | |
172 | ||
173 | /* Return true if a layout driver is being used for this mountpoint */ | |
174 | static inline int pnfs_enabled_sb(struct nfs_server *nfss) | |
175 | { | |
176 | return nfss->pnfs_curr_ld != NULL; | |
177 | } | |
85e174ba RL |
178 | |
179 | #else /* CONFIG_NFS_V4_1 */ | |
180 | ||
974cec8c AA |
181 | static inline void pnfs_destroy_all_layouts(struct nfs_client *clp) |
182 | { | |
183 | } | |
184 | ||
e5e94017 BH |
185 | static inline void pnfs_destroy_layout(struct nfs_inode *nfsi) |
186 | { | |
187 | } | |
188 | ||
189 | static inline struct pnfs_layout_segment * | |
190 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, | |
191 | enum pnfs_iomode access_type) | |
192 | { | |
193 | return NULL; | |
194 | } | |
195 | ||
85e174ba RL |
196 | static inline void set_pnfs_layoutdriver(struct nfs_server *s, u32 id) |
197 | { | |
198 | } | |
199 | ||
200 | static inline void unset_pnfs_layoutdriver(struct nfs_server *s) | |
201 | { | |
202 | } | |
203 | ||
204 | #endif /* CONFIG_NFS_V4_1 */ | |
205 | ||
206 | #endif /* FS_NFS_PNFS_H */ |