Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
423 | giacomo | 1 | /* |
2 | * linux/include/nfsd/state.h |
||
3 | * |
||
4 | * Copyright (c) 2001 The Regents of the University of Michigan. |
||
5 | * All rights reserved. |
||
6 | * |
||
7 | * Kendrick Smith <kmsmith@umich.edu> |
||
8 | * Andy Adamson <andros@umich.edu> |
||
9 | * |
||
10 | * Redistribution and use in source and binary forms, with or without |
||
11 | * modification, are permitted provided that the following conditions |
||
12 | * are met: |
||
13 | * |
||
14 | * 1. Redistributions of source code must retain the above copyright |
||
15 | * notice, this list of conditions and the following disclaimer. |
||
16 | * 2. Redistributions in binary form must reproduce the above copyright |
||
17 | * notice, this list of conditions and the following disclaimer in the |
||
18 | * documentation and/or other materials provided with the distribution. |
||
19 | * 3. Neither the name of the University nor the names of its |
||
20 | * contributors may be used to endorse or promote products derived |
||
21 | * from this software without specific prior written permission. |
||
22 | * |
||
23 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED |
||
24 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
||
25 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||
26 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
||
27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||
28 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||
29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
||
30 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||
31 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||
32 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||
33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
34 | * |
||
35 | */ |
||
36 | |||
37 | #ifndef _NFSD4_STATE_H |
||
38 | #define _NFSD4_STATE_H |
||
39 | |||
40 | #include <linux/list.h> |
||
41 | |||
42 | #define NFS4_OPAQUE_LIMIT 1024 |
||
43 | typedef struct { |
||
44 | u32 cl_boot; |
||
45 | u32 cl_id; |
||
46 | } clientid_t; |
||
47 | |||
48 | typedef struct { |
||
49 | u32 so_boot; |
||
50 | u32 so_stateownerid; |
||
51 | u32 so_fileid; |
||
52 | } stateid_opaque_t; |
||
53 | |||
54 | typedef struct { |
||
55 | u32 si_generation; |
||
56 | stateid_opaque_t si_opaque; |
||
57 | } stateid_t; |
||
58 | #define si_boot si_opaque.so_boot |
||
59 | #define si_stateownerid si_opaque.so_stateownerid |
||
60 | #define si_fileid si_opaque.so_fileid |
||
61 | |||
62 | extern stateid_t zerostateid; |
||
63 | extern stateid_t onestateid; |
||
64 | |||
65 | #define ZERO_STATEID(stateid) (!memcmp((stateid), &zerostateid, sizeof(stateid_t))) |
||
66 | #define ONE_STATEID(stateid) (!memcmp((stateid), &onestateid, sizeof(stateid_t))) |
||
67 | |||
68 | /* |
||
69 | * struct nfs4_client - one per client. Clientids live here. |
||
70 | * o Each nfs4_client is hashed by clientid. |
||
71 | * |
||
72 | * o Each nfs4_clients is also hashed by name |
||
73 | * (the opaque quantity initially sent by the client to identify itself). |
||
74 | * |
||
75 | * o cl_perclient list is used to ensure no dangling stateowner references |
||
76 | * when we expire the nfs4_client |
||
77 | */ |
||
78 | struct nfs4_client { |
||
79 | struct list_head cl_idhash; /* hash by cl_clientid.id */ |
||
80 | struct list_head cl_strhash; /* hash by cl_name */ |
||
81 | struct list_head cl_perclient; /* list: stateowners */ |
||
82 | struct list_head cl_lru; /* tail queue */ |
||
83 | struct xdr_netobj cl_name; /* id generated by client */ |
||
84 | nfs4_verifier cl_verifier; /* generated by client */ |
||
85 | time_t cl_time; /* time of last lease renewal */ |
||
86 | u32 cl_addr; /* client ipaddress */ |
||
87 | struct svc_cred cl_cred; /* setclientid principal */ |
||
88 | clientid_t cl_clientid; /* generated by server */ |
||
89 | nfs4_verifier cl_confirm; /* generated by server */ |
||
90 | }; |
||
91 | |||
92 | static inline void |
||
93 | update_stateid(stateid_t *stateid) |
||
94 | { |
||
95 | stateid->si_generation++; |
||
96 | } |
||
97 | |||
98 | /* A reasonable value for REPLAY_ISIZE was estimated as follows: |
||
99 | * The OPEN response, typically the largest, requires |
||
100 | * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) + |
||
101 | * 4(deleg. type) + 8(deleg. stateid) + 4(deleg. recall flag) + |
||
102 | * 20(deleg. space limit) + ~32(deleg. ace) = 112 bytes |
||
103 | */ |
||
104 | |||
105 | #define NFSD4_REPLAY_ISIZE 112 |
||
106 | |||
107 | /* |
||
108 | * Replay buffer, where the result of the last seqid-mutating operation |
||
109 | * is cached. |
||
110 | */ |
||
111 | struct nfs4_replay { |
||
112 | u32 rp_status; |
||
113 | unsigned int rp_buflen; |
||
114 | char *rp_buf; |
||
115 | unsigned intrp_allocated; |
||
116 | char rp_ibuf[NFSD4_REPLAY_ISIZE]; |
||
117 | }; |
||
118 | |||
119 | /* |
||
120 | * nfs4_stateowner can either be an open_owner, or a lock_owner |
||
121 | * |
||
122 | * so_idhash: stateid_hashtbl[] for open owner, lockstateid_hashtbl[] |
||
123 | * for lock_owner |
||
124 | * so_strhash: ownerstr_hashtbl[] for open_owner, lock_ownerstr_hashtbl[] |
||
125 | * for lock_owner |
||
126 | * so_perclient: nfs4_client->cl_perclient entry - used when nfs4_client |
||
127 | * struct is reaped. |
||
128 | * so_perfilestate: heads the list of nfs4_stateid (either open or lock) |
||
129 | * and is used to ensure no dangling nfs4_stateid references when we |
||
130 | * release a stateowner. |
||
131 | */ |
||
132 | struct nfs4_stateowner { |
||
133 | struct list_head so_idhash; /* hash by so_id */ |
||
134 | struct list_head so_strhash; /* hash by op_name */ |
||
135 | struct list_head so_perclient; /* nfs4_client->cl_perclient */ |
||
136 | struct list_head so_perfilestate; /* list: nfs4_stateid */ |
||
137 | int so_is_open_owner; /* 1=openowner,0=lockowner */ |
||
138 | u32 so_id; |
||
139 | struct nfs4_client * so_client; |
||
140 | u32 so_seqid; |
||
141 | struct xdr_netobj so_owner; /* open owner name */ |
||
142 | int so_confirmed; /* successful OPEN_CONFIRM? */ |
||
143 | struct nfs4_replay so_replay; |
||
144 | }; |
||
145 | |||
146 | /* |
||
147 | * nfs4_file: a file opened by some number of (open) nfs4_stateowners. |
||
148 | * o fi_perfile list is used to search for conflicting |
||
149 | * share_acces, share_deny on the file. |
||
150 | */ |
||
151 | struct nfs4_file { |
||
152 | struct list_head fi_hash; /* hash by "struct inode *" */ |
||
153 | struct list_head fi_perfile; /* list: nfs4_stateid */ |
||
154 | struct inode *fi_inode; |
||
155 | u32 fi_id; /* used with stateowner->so_id |
||
156 | * for stateid_hashtbl hash */ |
||
157 | }; |
||
158 | |||
159 | /* |
||
160 | * nfs4_stateid can either be an open stateid or (eventually) a lock stateid |
||
161 | * |
||
162 | * (open)nfs4_stateid: one per (open)nfs4_stateowner, nfs4_file |
||
163 | * |
||
164 | * st_hash: stateid_hashtbl[] entry or lockstateid_hashtbl entry |
||
165 | * st_perfile: file_hashtbl[] entry. |
||
166 | * st_perfile_state: nfs4_stateowner->so_perfilestate |
||
167 | * st_share_access: used only for open stateid |
||
168 | * st_share_deny: used only for open stateid |
||
169 | */ |
||
170 | |||
171 | struct nfs4_stateid { |
||
172 | struct list_head st_hash; |
||
173 | struct list_head st_perfile; |
||
174 | struct list_head st_perfilestate; |
||
175 | struct nfs4_stateowner * st_stateowner; |
||
176 | struct nfs4_file * st_file; |
||
177 | stateid_t st_stateid; |
||
178 | struct file st_vfs_file; |
||
179 | int st_vfs_set; |
||
180 | unsigned int st_share_access; |
||
181 | unsigned int st_share_deny; |
||
182 | }; |
||
183 | |||
184 | /* flags for preprocess_seqid_op() */ |
||
185 | #define CHECK_FH 0x00000001 |
||
186 | #define CONFIRM 0x00000002 |
||
187 | #define OPEN_STATE 0x00000004 |
||
188 | #define LOCK_STATE 0x00000008 |
||
189 | #define RDWR_STATE 0x00000010 |
||
190 | |||
191 | #define seqid_mutating_err(err) \ |
||
192 | (((err) != nfserr_stale_clientid) && \ |
||
193 | ((err) != nfserr_bad_seqid) && \ |
||
194 | ((err) != nfserr_stale_stateid) && \ |
||
195 | ((err) != nfserr_bad_stateid)) |
||
196 | |||
197 | extern time_t nfs4_laundromat(void); |
||
198 | extern int nfsd4_renew(clientid_t *clid); |
||
199 | extern int nfs4_preprocess_stateid_op(struct svc_fh *current_fh, |
||
200 | stateid_t *stateid, int flags, struct nfs4_stateid **stpp); |
||
201 | extern int nfs4_share_conflict(struct svc_fh *current_fh, |
||
202 | unsigned int deny_type); |
||
203 | extern void nfs4_lock_state(void); |
||
204 | extern void nfs4_unlock_state(void); |
||
205 | #endif /* NFSD4_STATE_H */ |