]>
Commit | Line | Data |
---|---|---|
ec26815a | 1 | /* internal AFS stuff |
1da177e4 | 2 | * |
08e0e7c8 | 3 | * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved. |
1da177e4 LT |
4 | * Written by David Howells (dhowells@redhat.com) |
5 | * | |
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public License | |
8 | * as published by the Free Software Foundation; either version | |
9 | * 2 of the License, or (at your option) any later version. | |
10 | */ | |
11 | ||
1da177e4 LT |
12 | #include <linux/compiler.h> |
13 | #include <linux/kernel.h> | |
8a79790b | 14 | #include <linux/ktime.h> |
1da177e4 LT |
15 | #include <linux/fs.h> |
16 | #include <linux/pagemap.h> | |
08e0e7c8 | 17 | #include <linux/rxrpc.h> |
00d3b7a4 | 18 | #include <linux/key.h> |
e8edc6e0 | 19 | #include <linux/workqueue.h> |
00c541ea | 20 | #include <linux/sched.h> |
80e50be4 | 21 | #include <linux/fscache.h> |
e1da0222 | 22 | #include <linux/backing-dev.h> |
ff548773 | 23 | #include <linux/uuid.h> |
f044c884 | 24 | #include <net/net_namespace.h> |
8324f0bc | 25 | #include <net/af_rxrpc.h> |
00c541ea | 26 | |
08e0e7c8 DH |
27 | #include "afs.h" |
28 | #include "afs_vl.h" | |
29 | ||
30 | #define AFS_CELL_MAX_ADDRS 15 | |
31 | ||
31143d5d | 32 | struct pagevec; |
08e0e7c8 DH |
33 | struct afs_call; |
34 | ||
35 | typedef enum { | |
36 | AFS_VL_NEW, /* new, uninitialised record */ | |
37 | AFS_VL_CREATING, /* creating record */ | |
38 | AFS_VL_VALID, /* record is pending */ | |
39 | AFS_VL_NO_VOLUME, /* no such volume available */ | |
40 | AFS_VL_UPDATING, /* update in progress */ | |
41 | AFS_VL_VOLUME_DELETED, /* volume was deleted */ | |
42 | AFS_VL_UNCERTAIN, /* uncertain state (update failed) */ | |
43 | } __attribute__((packed)) afs_vlocation_state_t; | |
1da177e4 | 44 | |
00d3b7a4 DH |
45 | struct afs_mount_params { |
46 | bool rwpath; /* T if the parent should be considered R/W */ | |
47 | bool force; /* T to force cell type */ | |
bec5eb61 | 48 | bool autocell; /* T if set auto mount operation */ |
00d3b7a4 DH |
49 | afs_voltype_t type; /* type of volume requested */ |
50 | int volnamesz; /* size of volume name */ | |
51 | const char *volname; /* name of volume to mount */ | |
f044c884 | 52 | struct afs_net *net; /* Network namespace in effect */ |
00d3b7a4 DH |
53 | struct afs_cell *cell; /* cell in which to find volume */ |
54 | struct afs_volume *volume; /* volume record */ | |
55 | struct key *key; /* key to use for secure mounting */ | |
56 | }; | |
57 | ||
c435ee34 DH |
58 | struct afs_iget_data { |
59 | struct afs_fid fid; | |
60 | struct afs_volume *volume; /* volume on which resides */ | |
61 | }; | |
62 | ||
8e8d7f13 DH |
63 | enum afs_call_state { |
64 | AFS_CALL_REQUESTING, /* request is being sent for outgoing call */ | |
65 | AFS_CALL_AWAIT_REPLY, /* awaiting reply to outgoing call */ | |
66 | AFS_CALL_AWAIT_OP_ID, /* awaiting op ID on incoming call */ | |
67 | AFS_CALL_AWAIT_REQUEST, /* awaiting request data on incoming call */ | |
68 | AFS_CALL_REPLYING, /* replying to incoming call */ | |
69 | AFS_CALL_AWAIT_ACK, /* awaiting final ACK of incoming call */ | |
70 | AFS_CALL_COMPLETE, /* Completed or failed */ | |
71 | }; | |
f044c884 | 72 | |
08e0e7c8 DH |
73 | /* |
74 | * a record of an in-progress RxRPC call | |
75 | */ | |
76 | struct afs_call { | |
77 | const struct afs_call_type *type; /* type of call */ | |
08e0e7c8 | 78 | wait_queue_head_t waitq; /* processes awaiting completion */ |
341f741f | 79 | struct work_struct async_work; /* async I/O processor */ |
08e0e7c8 | 80 | struct work_struct work; /* actual work processor */ |
08e0e7c8 DH |
81 | struct rxrpc_call *rxcall; /* RxRPC call handle */ |
82 | struct key *key; /* security for this call */ | |
f044c884 | 83 | struct afs_net *net; /* The network namespace */ |
d0676a16 | 84 | struct afs_server *cm_server; /* Server affected by incoming CM call */ |
c435ee34 | 85 | struct afs_server *server; /* Server used by client call */ |
08e0e7c8 | 86 | void *request; /* request data (first part) */ |
31143d5d DH |
87 | struct address_space *mapping; /* page set */ |
88 | struct afs_writeback *wb; /* writeback being performed */ | |
08e0e7c8 | 89 | void *buffer; /* reply receive buffer */ |
97e3043a | 90 | void *reply[4]; /* Where to put the reply */ |
31143d5d DH |
91 | pgoff_t first; /* first page in mapping to deal with */ |
92 | pgoff_t last; /* last page in mapping to deal with */ | |
d001648e | 93 | size_t offset; /* offset into received data store */ |
341f741f | 94 | atomic_t usage; |
8e8d7f13 | 95 | enum afs_call_state state; |
08e0e7c8 | 96 | int error; /* error code */ |
d001648e | 97 | u32 abort_code; /* Remote abort ID or 0 */ |
08e0e7c8 DH |
98 | unsigned request_size; /* size of request data */ |
99 | unsigned reply_max; /* maximum size of reply */ | |
31143d5d | 100 | unsigned first_offset; /* offset into mapping[first] */ |
c435ee34 | 101 | unsigned int cb_break; /* cb_break + cb_s_break before the call */ |
bcd89270 MD |
102 | union { |
103 | unsigned last_to; /* amount of mapping[last] */ | |
104 | unsigned count2; /* count used in unmarshalling */ | |
105 | }; | |
08e0e7c8 DH |
106 | unsigned char unmarshall; /* unmarshalling phase */ |
107 | bool incoming; /* T if incoming call */ | |
31143d5d | 108 | bool send_pages; /* T if data from mapping should be sent */ |
d001648e | 109 | bool need_attention; /* T if RxRPC poked us */ |
56ff9c83 | 110 | bool async; /* T if asynchronous */ |
33cd7f2b | 111 | bool ret_reply0; /* T if should return reply[0] on success */ |
a68f4a27 | 112 | bool upgrade; /* T to request service upgrade */ |
08e0e7c8 | 113 | u16 service_id; /* RxRPC service ID to call */ |
50a2c953 | 114 | u32 operation_ID; /* operation ID for an incoming call */ |
08e0e7c8 DH |
115 | u32 count; /* count for use in unmarshalling */ |
116 | __be32 tmp; /* place to extract temporary data */ | |
31143d5d | 117 | afs_dataversion_t store_version; /* updated version expected from store */ |
08e0e7c8 DH |
118 | }; |
119 | ||
120 | struct afs_call_type { | |
00d3b7a4 DH |
121 | const char *name; |
122 | ||
08e0e7c8 DH |
123 | /* deliver request or reply data to an call |
124 | * - returning an error will cause the call to be aborted | |
125 | */ | |
d001648e | 126 | int (*deliver)(struct afs_call *call); |
08e0e7c8 | 127 | |
08e0e7c8 DH |
128 | /* clean up a call */ |
129 | void (*destructor)(struct afs_call *call); | |
341f741f DH |
130 | |
131 | /* Work function */ | |
132 | void (*work)(struct work_struct *work); | |
08e0e7c8 DH |
133 | }; |
134 | ||
196ee9cd DH |
135 | /* |
136 | * Record of an outstanding read operation on a vnode. | |
137 | */ | |
138 | struct afs_read { | |
139 | loff_t pos; /* Where to start reading */ | |
e8e581a8 | 140 | loff_t len; /* How much we're asking for */ |
196ee9cd | 141 | loff_t actual_len; /* How much we're actually getting */ |
6a0e3999 | 142 | loff_t remain; /* Amount remaining */ |
196ee9cd | 143 | atomic_t usage; |
196ee9cd | 144 | unsigned int index; /* Which page we're reading into */ |
196ee9cd DH |
145 | unsigned int nr_pages; |
146 | void (*page_done)(struct afs_call *, struct afs_read *); | |
147 | struct page *pages[]; | |
148 | }; | |
149 | ||
31143d5d DH |
150 | /* |
151 | * record of an outstanding writeback on a vnode | |
152 | */ | |
153 | struct afs_writeback { | |
154 | struct list_head link; /* link in vnode->writebacks */ | |
155 | struct work_struct writer; /* work item to perform the writeback */ | |
156 | struct afs_vnode *vnode; /* vnode to which this write applies */ | |
157 | struct key *key; /* owner of this write */ | |
158 | wait_queue_head_t waitq; /* completion and ready wait queue */ | |
159 | pgoff_t first; /* first page in batch */ | |
160 | pgoff_t point; /* last page in current store op */ | |
161 | pgoff_t last; /* last page in batch (inclusive) */ | |
162 | unsigned offset_first; /* offset into first page of start of write */ | |
163 | unsigned to_last; /* offset into last page of end of write */ | |
164 | int num_conflicts; /* count of conflicting writes in list */ | |
165 | int usage; | |
166 | bool conflicts; /* T if has dependent conflicts */ | |
167 | enum { | |
168 | AFS_WBACK_SYNCING, /* synchronisation being performed */ | |
169 | AFS_WBACK_PENDING, /* write pending */ | |
170 | AFS_WBACK_CONFLICTING, /* conflicting writes posted */ | |
171 | AFS_WBACK_WRITING, /* writing back */ | |
172 | AFS_WBACK_COMPLETE /* the writeback record has been unlinked */ | |
173 | } state __attribute__((packed)); | |
174 | }; | |
175 | ||
08e0e7c8 DH |
176 | /* |
177 | * AFS superblock private data | |
178 | * - there's one superblock per volume | |
179 | */ | |
180 | struct afs_super_info { | |
f044c884 | 181 | struct afs_net *net; /* Network namespace */ |
49566f6f | 182 | struct afs_cell *cell; /* The cell in which the volume resides */ |
08e0e7c8 DH |
183 | struct afs_volume *volume; /* volume record */ |
184 | char rwparent; /* T if parent is R/W AFS volume */ | |
185 | }; | |
1da177e4 | 186 | |
08e0e7c8 DH |
187 | static inline struct afs_super_info *AFS_FS_S(struct super_block *sb) |
188 | { | |
189 | return sb->s_fs_info; | |
1da177e4 LT |
190 | } |
191 | ||
08e0e7c8 DH |
192 | extern struct file_system_type afs_fs_type; |
193 | ||
f044c884 DH |
194 | /* |
195 | * AFS network namespace record. | |
196 | */ | |
197 | struct afs_net { | |
198 | struct afs_uuid uuid; | |
199 | bool live; /* F if this namespace is being removed */ | |
200 | ||
201 | /* AF_RXRPC I/O stuff */ | |
202 | struct socket *socket; | |
203 | struct afs_call *spare_incoming_call; | |
204 | struct work_struct charge_preallocation_work; | |
205 | struct mutex socket_mutex; | |
206 | atomic_t nr_outstanding_calls; | |
207 | atomic_t nr_superblocks; | |
208 | ||
209 | /* Cell database */ | |
989782dc | 210 | struct rb_root cells; |
f044c884 | 211 | struct afs_cell *ws_cell; |
989782dc DH |
212 | struct work_struct cells_manager; |
213 | struct timer_list cells_timer; | |
214 | atomic_t cells_outstanding; | |
215 | seqlock_t cells_lock; | |
f044c884 | 216 | |
989782dc | 217 | spinlock_t proc_cells_lock; |
f044c884 DH |
218 | struct list_head proc_cells; |
219 | ||
220 | /* Volume location database */ | |
221 | struct list_head vl_updates; /* VL records in need-update order */ | |
222 | struct list_head vl_graveyard; /* Inactive VL records */ | |
223 | struct delayed_work vl_reaper; | |
224 | struct delayed_work vl_updater; | |
225 | spinlock_t vl_updates_lock; | |
226 | spinlock_t vl_graveyard_lock; | |
227 | ||
228 | /* File locking renewal management */ | |
229 | struct mutex lock_manager_mutex; | |
230 | ||
231 | /* Server database */ | |
232 | struct rb_root servers; /* Active servers */ | |
233 | rwlock_t servers_lock; | |
234 | struct list_head server_graveyard; /* Inactive server LRU list */ | |
235 | spinlock_t server_graveyard_lock; | |
59fa1c4a DH |
236 | struct timer_list server_timer; |
237 | struct work_struct server_reaper; | |
238 | atomic_t servers_outstanding; | |
f044c884 DH |
239 | |
240 | /* Misc */ | |
241 | struct proc_dir_entry *proc_afs; /* /proc/net/afs directory */ | |
242 | }; | |
243 | ||
244 | extern struct afs_net __afs_net;// Dummy AFS network namespace; TODO: replace with real netns | |
245 | ||
989782dc DH |
246 | enum afs_cell_state { |
247 | AFS_CELL_UNSET, | |
248 | AFS_CELL_ACTIVATING, | |
249 | AFS_CELL_ACTIVE, | |
250 | AFS_CELL_DEACTIVATING, | |
251 | AFS_CELL_INACTIVE, | |
252 | AFS_CELL_FAILED, | |
253 | }; | |
254 | ||
08e0e7c8 DH |
255 | /* |
256 | * AFS cell record | |
257 | */ | |
258 | struct afs_cell { | |
989782dc DH |
259 | union { |
260 | struct rcu_head rcu; | |
261 | struct rb_node net_node; /* Node in net->cells */ | |
262 | }; | |
263 | struct afs_net *net; | |
00d3b7a4 | 264 | struct key *anonymous_key; /* anonymous user key for this cell */ |
989782dc | 265 | struct work_struct manager; /* Manager for init/deinit/dns */ |
08e0e7c8 | 266 | struct list_head proc_link; /* /proc cell list link */ |
9b3f26c9 DH |
267 | #ifdef CONFIG_AFS_FSCACHE |
268 | struct fscache_cookie *cache; /* caching cookie */ | |
08e0e7c8 DH |
269 | #endif |
270 | ||
271 | /* server record management */ | |
272 | rwlock_t servers_lock; /* active server list lock */ | |
273 | struct list_head servers; /* active server list */ | |
274 | ||
275 | /* volume location record management */ | |
276 | struct rw_semaphore vl_sem; /* volume management serialisation semaphore */ | |
277 | struct list_head vl_list; /* cell's active VL record list */ | |
989782dc DH |
278 | time64_t dns_expiry; /* Time AFSDB/SRV record expires */ |
279 | time64_t last_inactive; /* Time of last drop of usage count */ | |
280 | atomic_t usage; | |
281 | unsigned long flags; | |
282 | #define AFS_CELL_FL_NOT_READY 0 /* The cell record is not ready for use */ | |
283 | #define AFS_CELL_FL_NO_GC 1 /* The cell was added manually, don't auto-gc */ | |
284 | #define AFS_CELL_FL_NOT_FOUND 2 /* Permanent DNS error */ | |
285 | #define AFS_CELL_FL_DNS_FAIL 3 /* Failed to access DNS */ | |
286 | enum afs_cell_state state; | |
287 | short error; | |
288 | ||
08e0e7c8 | 289 | spinlock_t vl_lock; /* vl_list lock */ |
989782dc DH |
290 | |
291 | /* VLDB server list. */ | |
292 | seqlock_t vl_addrs_lock; | |
08e0e7c8 DH |
293 | unsigned short vl_naddrs; /* number of VL servers in addr list */ |
294 | unsigned short vl_curr_svix; /* current server index */ | |
4d9df986 | 295 | struct sockaddr_rxrpc vl_addrs[AFS_CELL_MAX_ADDRS]; /* cell VL server addresses */ |
989782dc DH |
296 | u8 name_len; /* Length of name */ |
297 | char name[64 + 1]; /* Cell name, case-flattened and NUL-padded */ | |
08e0e7c8 DH |
298 | }; |
299 | ||
300 | /* | |
301 | * entry in the cached volume location catalogue | |
302 | */ | |
303 | struct afs_cache_vlocation { | |
00d3b7a4 DH |
304 | /* volume name (lowercase, padded with NULs) */ |
305 | uint8_t name[AFS_MAXVOLNAME + 1]; | |
306 | ||
08e0e7c8 DH |
307 | uint8_t nservers; /* number of entries used in servers[] */ |
308 | uint8_t vidmask; /* voltype mask for vid[] */ | |
309 | uint8_t srvtmask[8]; /* voltype masks for servers[] */ | |
310 | #define AFS_VOL_VTM_RW 0x01 /* R/W version of the volume is available (on this server) */ | |
311 | #define AFS_VOL_VTM_RO 0x02 /* R/O version of the volume is available (on this server) */ | |
312 | #define AFS_VOL_VTM_BAK 0x04 /* backup version of the volume is available (on this server) */ | |
313 | ||
314 | afs_volid_t vid[3]; /* volume IDs for R/W, R/O and Bak volumes */ | |
4d9df986 | 315 | struct sockaddr_rxrpc servers[8]; /* fileserver addresses */ |
08e0e7c8 DH |
316 | time_t rtime; /* last retrieval time */ |
317 | }; | |
318 | ||
08e0e7c8 DH |
319 | /* |
320 | * AFS volume location record | |
321 | */ | |
322 | struct afs_vlocation { | |
323 | atomic_t usage; | |
8a79790b | 324 | time64_t time_of_death; /* time at which put reduced usage to 0 */ |
08e0e7c8 DH |
325 | struct list_head link; /* link in cell volume location list */ |
326 | struct list_head grave; /* link in master graveyard list */ | |
327 | struct list_head update; /* link in master update list */ | |
328 | struct afs_cell *cell; /* cell to which volume belongs */ | |
08e0e7c8 DH |
329 | struct afs_cache_vlocation vldb; /* volume information DB record */ |
330 | struct afs_volume *vols[3]; /* volume access record pointer (index by type) */ | |
331 | wait_queue_head_t waitq; /* status change waitqueue */ | |
8a79790b | 332 | time64_t update_at; /* time at which record should be updated */ |
39bf0949 | 333 | spinlock_t lock; /* access lock */ |
08e0e7c8 DH |
334 | afs_vlocation_state_t state; /* volume location state */ |
335 | unsigned short upd_rej_cnt; /* ENOMEDIUM count during update */ | |
336 | unsigned short upd_busy_cnt; /* EBUSY count during update */ | |
337 | bool valid; /* T if valid */ | |
338 | }; | |
339 | ||
340 | /* | |
341 | * AFS fileserver record | |
342 | */ | |
343 | struct afs_server { | |
344 | atomic_t usage; | |
8a79790b | 345 | time64_t time_of_death; /* time at which put reduced usage to 0 */ |
4d9df986 | 346 | struct sockaddr_rxrpc addr; /* server address */ |
9ed900b1 | 347 | struct afs_net *net; /* Network namespace in which the server resides */ |
08e0e7c8 DH |
348 | struct afs_cell *cell; /* cell in which server resides */ |
349 | struct list_head link; /* link in cell's server list */ | |
350 | struct list_head grave; /* link in master graveyard list */ | |
c435ee34 | 351 | |
08e0e7c8 DH |
352 | struct rb_node master_rb; /* link in master by-addr tree */ |
353 | struct rw_semaphore sem; /* access lock */ | |
c435ee34 DH |
354 | unsigned long flags; |
355 | #define AFS_SERVER_NEW 0 /* New server, don't inc cb_s_break */ | |
08e0e7c8 DH |
356 | |
357 | /* file service access */ | |
08e0e7c8 | 358 | int fs_state; /* 0 or reason FS currently marked dead (-errno) */ |
c435ee34 | 359 | spinlock_t fs_lock; /* access lock */ |
08e0e7c8 DH |
360 | |
361 | /* callback promise management */ | |
c435ee34 DH |
362 | struct list_head cb_interests; /* List of superblocks using this server */ |
363 | unsigned cb_s_break; /* Break-everything counter. */ | |
364 | rwlock_t cb_break_lock; /* Volume finding lock */ | |
365 | }; | |
366 | ||
367 | /* | |
368 | * Interest by a superblock on a server. | |
369 | */ | |
370 | struct afs_cb_interest { | |
371 | struct list_head cb_link; /* Link in server->cb_interests */ | |
372 | struct afs_server *server; /* Server on which this interest resides */ | |
373 | struct super_block *sb; /* Superblock on which inodes reside */ | |
374 | afs_volid_t vid; /* Volume ID to match */ | |
375 | refcount_t usage; | |
08e0e7c8 DH |
376 | }; |
377 | ||
378 | /* | |
379 | * AFS volume access record | |
380 | */ | |
381 | struct afs_volume { | |
382 | atomic_t usage; | |
383 | struct afs_cell *cell; /* cell to which belongs (unrefd ptr) */ | |
384 | struct afs_vlocation *vlocation; /* volume location */ | |
9b3f26c9 DH |
385 | #ifdef CONFIG_AFS_FSCACHE |
386 | struct fscache_cookie *cache; /* caching cookie */ | |
08e0e7c8 DH |
387 | #endif |
388 | afs_volid_t vid; /* volume ID */ | |
389 | afs_voltype_t type; /* type of volume */ | |
390 | char type_force; /* force volume type (suppress R/O -> R/W) */ | |
391 | unsigned short nservers; /* number of server slots filled */ | |
392 | unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */ | |
393 | struct afs_server *servers[8]; /* servers on which volume resides (ordered) */ | |
c435ee34 | 394 | struct afs_cb_interest *cb_interests[8]; /* Interests on servers for callbacks */ |
08e0e7c8 DH |
395 | struct rw_semaphore server_sem; /* lock for accessing current server */ |
396 | }; | |
397 | ||
398 | /* | |
399 | * vnode catalogue entry | |
400 | */ | |
401 | struct afs_cache_vnode { | |
402 | afs_vnodeid_t vnode_id; /* vnode ID */ | |
403 | unsigned vnode_unique; /* vnode ID uniquifier */ | |
404 | afs_dataversion_t data_version; /* data version */ | |
405 | }; | |
406 | ||
407 | /* | |
408 | * AFS inode private data | |
409 | */ | |
410 | struct afs_vnode { | |
411 | struct inode vfs_inode; /* the VFS's inode record */ | |
412 | ||
413 | struct afs_volume *volume; /* volume on which vnode resides */ | |
08e0e7c8 DH |
414 | struct afs_fid fid; /* the file identifier for this inode */ |
415 | struct afs_file_status status; /* AFS status info for this file */ | |
9b3f26c9 DH |
416 | #ifdef CONFIG_AFS_FSCACHE |
417 | struct fscache_cookie *cache; /* caching cookie */ | |
08e0e7c8 | 418 | #endif |
be080a6f | 419 | struct afs_permits *permit_cache; /* cache of permits so far obtained */ |
260a9803 | 420 | struct mutex validate_lock; /* lock for validating this vnode */ |
08e0e7c8 | 421 | wait_queue_head_t update_waitq; /* status fetch waitqueue */ |
260a9803 | 422 | int update_cnt; /* number of outstanding ops that will update the |
08e0e7c8 | 423 | * status */ |
31143d5d | 424 | spinlock_t writeback_lock; /* lock for writebacks */ |
08e0e7c8 DH |
425 | spinlock_t lock; /* waitqueue/flags lock */ |
426 | unsigned long flags; | |
c435ee34 | 427 | #define AFS_VNODE_CB_PROMISED 0 /* Set if vnode has a callback promise */ |
260a9803 | 428 | #define AFS_VNODE_UNSET 1 /* set if vnode attributes not yet set */ |
c435ee34 | 429 | #define AFS_VNODE_DIR_MODIFIED 2 /* set if dir vnode's data modified */ |
08e0e7c8 DH |
430 | #define AFS_VNODE_ZAP_DATA 3 /* set if vnode's data should be invalidated */ |
431 | #define AFS_VNODE_DELETED 4 /* set if vnode deleted on server */ | |
432 | #define AFS_VNODE_MOUNTPOINT 5 /* set if vnode is a mountpoint symlink */ | |
e8d6c554 DH |
433 | #define AFS_VNODE_LOCKING 6 /* set if waiting for lock on vnode */ |
434 | #define AFS_VNODE_READLOCKED 7 /* set if vnode is read-locked on the server */ | |
435 | #define AFS_VNODE_WRITELOCKED 8 /* set if vnode is write-locked on the server */ | |
436 | #define AFS_VNODE_UNLOCKING 9 /* set if vnode is being unlocked on the server */ | |
bec5eb61 | 437 | #define AFS_VNODE_AUTOCELL 10 /* set if Vnode is an auto mount point */ |
438 | #define AFS_VNODE_PSEUDODIR 11 /* set if Vnode is a pseudo directory */ | |
08e0e7c8 | 439 | |
31143d5d | 440 | struct list_head writebacks; /* alterations in pagecache that need writing */ |
e8d6c554 DH |
441 | struct list_head pending_locks; /* locks waiting to be granted */ |
442 | struct list_head granted_locks; /* locks granted on this file */ | |
443 | struct delayed_work lock_work; /* work to be done in locking */ | |
444 | struct key *unlock_key; /* key to be used in unlocking */ | |
31143d5d | 445 | |
08e0e7c8 | 446 | /* outstanding callback notification on this file */ |
c435ee34 DH |
447 | struct afs_cb_interest *cb_interest; /* Server on which this resides */ |
448 | unsigned int cb_s_break; /* Mass break counter on ->server */ | |
449 | unsigned int cb_break; /* Break counter on vnode */ | |
450 | seqlock_t cb_lock; /* Lock for ->cb_interest, ->status, ->cb_*break */ | |
451 | ||
452 | time64_t cb_expires_at; /* time at which callback expires */ | |
08e0e7c8 | 453 | unsigned cb_version; /* callback version */ |
08e0e7c8 | 454 | afs_callback_type_t cb_type; /* type of callback */ |
08e0e7c8 DH |
455 | }; |
456 | ||
00d3b7a4 DH |
457 | /* |
458 | * cached security record for one user's attempt to access a vnode | |
459 | */ | |
460 | struct afs_permit { | |
461 | struct key *key; /* RxRPC ticket holding a security context */ | |
be080a6f | 462 | afs_access_t access; /* CallerAccess value for this key */ |
00d3b7a4 DH |
463 | }; |
464 | ||
465 | /* | |
be080a6f DH |
466 | * Immutable cache of CallerAccess records from attempts to access vnodes. |
467 | * These may be shared between multiple vnodes. | |
00d3b7a4 DH |
468 | */ |
469 | struct afs_permits { | |
be080a6f DH |
470 | struct rcu_head rcu; |
471 | struct hlist_node hash_node; /* Link in hash */ | |
472 | unsigned long h; /* Hash value for this permit list */ | |
473 | refcount_t usage; | |
474 | unsigned short nr_permits; /* Number of records */ | |
475 | bool invalidated; /* Invalidated due to key change */ | |
476 | struct afs_permit permits[]; /* List of permits sorted by key pointer */ | |
00d3b7a4 DH |
477 | }; |
478 | ||
b908fe6b DH |
479 | /* |
480 | * record of one of a system's set of network interfaces | |
481 | */ | |
482 | struct afs_interface { | |
b908fe6b DH |
483 | struct in_addr address; /* IPv4 address bound to interface */ |
484 | struct in_addr netmask; /* netmask applied to address */ | |
485 | unsigned mtu; /* MTU of interface */ | |
486 | }; | |
487 | ||
08e0e7c8 | 488 | /*****************************************************************************/ |
9b3f26c9 DH |
489 | /* |
490 | * cache.c | |
491 | */ | |
492 | #ifdef CONFIG_AFS_FSCACHE | |
493 | extern struct fscache_netfs afs_cache_netfs; | |
494 | extern struct fscache_cookie_def afs_cell_cache_index_def; | |
9b3f26c9 DH |
495 | extern struct fscache_cookie_def afs_volume_cache_index_def; |
496 | extern struct fscache_cookie_def afs_vnode_cache_index_def; | |
497 | #else | |
498 | #define afs_cell_cache_index_def (*(struct fscache_cookie_def *) NULL) | |
9b3f26c9 DH |
499 | #define afs_volume_cache_index_def (*(struct fscache_cookie_def *) NULL) |
500 | #define afs_vnode_cache_index_def (*(struct fscache_cookie_def *) NULL) | |
501 | #endif | |
502 | ||
08e0e7c8 DH |
503 | /* |
504 | * callback.c | |
505 | */ | |
506 | extern void afs_init_callback_state(struct afs_server *); | |
c435ee34 DH |
507 | extern void afs_break_callback(struct afs_vnode *); |
508 | extern void afs_break_callbacks(struct afs_server *, size_t,struct afs_callback[]); | |
509 | ||
510 | extern int afs_register_server_cb_interest(struct afs_vnode *, struct afs_cb_interest **, | |
511 | struct afs_server *); | |
512 | extern void afs_put_cb_interest(struct afs_net *, struct afs_cb_interest *); | |
513 | extern void afs_clear_callback_interests(struct afs_net *, struct afs_volume *); | |
514 | ||
515 | static inline struct afs_cb_interest *afs_get_cb_interest(struct afs_cb_interest *cbi) | |
516 | { | |
517 | refcount_inc(&cbi->usage); | |
518 | return cbi; | |
519 | } | |
08e0e7c8 | 520 | |
1da177e4 LT |
521 | /* |
522 | * cell.c | |
523 | */ | |
989782dc | 524 | static inline struct afs_cell *afs_get_cell(struct afs_cell *cell) |
49566f6f DH |
525 | { |
526 | if (cell) | |
527 | atomic_inc(&cell->usage); | |
528 | return cell; | |
529 | } | |
989782dc DH |
530 | |
531 | extern int afs_cell_init(struct afs_net *, const char *); | |
532 | extern struct afs_cell *afs_lookup_cell_rcu(struct afs_net *, const char *, unsigned); | |
533 | extern struct afs_cell *afs_lookup_cell(struct afs_net *, const char *, unsigned, | |
534 | const char *, bool); | |
9ed900b1 | 535 | extern void afs_put_cell(struct afs_net *, struct afs_cell *); |
989782dc DH |
536 | extern void afs_manage_cells(struct work_struct *); |
537 | extern void afs_cells_timer(struct timer_list *); | |
f044c884 | 538 | extern void __net_exit afs_cell_purge(struct afs_net *); |
08e0e7c8 DH |
539 | |
540 | /* | |
541 | * cmservice.c | |
542 | */ | |
543 | extern bool afs_cm_incoming_call(struct afs_call *); | |
544 | ||
1da177e4 LT |
545 | /* |
546 | * dir.c | |
547 | */ | |
754661f1 | 548 | extern const struct inode_operations afs_dir_inode_operations; |
d61dcce2 | 549 | extern const struct dentry_operations afs_fs_dentry_operations; |
4b6f5d20 | 550 | extern const struct file_operations afs_dir_file_operations; |
1da177e4 LT |
551 | |
552 | /* | |
553 | * file.c | |
554 | */ | |
f5e54d6e | 555 | extern const struct address_space_operations afs_fs_aops; |
754661f1 | 556 | extern const struct inode_operations afs_file_inode_operations; |
00d3b7a4 DH |
557 | extern const struct file_operations afs_file_operations; |
558 | ||
559 | extern int afs_open(struct inode *, struct file *); | |
560 | extern int afs_release(struct inode *, struct file *); | |
f6d335c0 | 561 | extern int afs_page_filler(void *, struct page *); |
196ee9cd | 562 | extern void afs_put_read(struct afs_read *); |
1da177e4 | 563 | |
e8d6c554 DH |
564 | /* |
565 | * flock.c | |
566 | */ | |
f044c884 DH |
567 | extern struct workqueue_struct *afs_lock_manager; |
568 | ||
e8d6c554 DH |
569 | extern void afs_lock_work(struct work_struct *); |
570 | extern void afs_lock_may_be_available(struct afs_vnode *); | |
571 | extern int afs_lock(struct file *, int, struct file_lock *); | |
572 | extern int afs_flock(struct file *, int, struct file_lock *); | |
573 | ||
08e0e7c8 DH |
574 | /* |
575 | * fsclient.c | |
576 | */ | |
00d3b7a4 DH |
577 | extern int afs_fs_fetch_file_status(struct afs_server *, struct key *, |
578 | struct afs_vnode *, struct afs_volsync *, | |
56ff9c83 | 579 | bool); |
f044c884 | 580 | extern int afs_fs_give_up_callbacks(struct afs_net *, struct afs_server *, bool); |
00d3b7a4 | 581 | extern int afs_fs_fetch_data(struct afs_server *, struct key *, |
56ff9c83 | 582 | struct afs_vnode *, struct afs_read *, bool); |
260a9803 DH |
583 | extern int afs_fs_create(struct afs_server *, struct key *, |
584 | struct afs_vnode *, const char *, umode_t, | |
585 | struct afs_fid *, struct afs_file_status *, | |
56ff9c83 | 586 | struct afs_callback *, bool); |
260a9803 | 587 | extern int afs_fs_remove(struct afs_server *, struct key *, |
56ff9c83 | 588 | struct afs_vnode *, const char *, bool, bool); |
260a9803 | 589 | extern int afs_fs_link(struct afs_server *, struct key *, struct afs_vnode *, |
56ff9c83 | 590 | struct afs_vnode *, const char *, bool); |
260a9803 DH |
591 | extern int afs_fs_symlink(struct afs_server *, struct key *, |
592 | struct afs_vnode *, const char *, const char *, | |
56ff9c83 | 593 | struct afs_fid *, struct afs_file_status *, bool); |
260a9803 DH |
594 | extern int afs_fs_rename(struct afs_server *, struct key *, |
595 | struct afs_vnode *, const char *, | |
56ff9c83 | 596 | struct afs_vnode *, const char *, bool); |
31143d5d | 597 | extern int afs_fs_store_data(struct afs_server *, struct afs_writeback *, |
56ff9c83 | 598 | pgoff_t, pgoff_t, unsigned, unsigned, bool); |
31143d5d | 599 | extern int afs_fs_setattr(struct afs_server *, struct key *, |
56ff9c83 | 600 | struct afs_vnode *, struct iattr *, bool); |
45222b9e DH |
601 | extern int afs_fs_get_volume_status(struct afs_server *, struct key *, |
602 | struct afs_vnode *, | |
56ff9c83 | 603 | struct afs_volume_status *, bool); |
e8d6c554 | 604 | extern int afs_fs_set_lock(struct afs_server *, struct key *, |
56ff9c83 | 605 | struct afs_vnode *, afs_lock_type_t, bool); |
e8d6c554 | 606 | extern int afs_fs_extend_lock(struct afs_server *, struct key *, |
56ff9c83 | 607 | struct afs_vnode *, bool); |
e8d6c554 | 608 | extern int afs_fs_release_lock(struct afs_server *, struct key *, |
56ff9c83 | 609 | struct afs_vnode *, bool); |
c435ee34 | 610 | extern int afs_fs_give_up_all_callbacks(struct afs_server *, struct key *, bool); |
08e0e7c8 | 611 | |
1da177e4 LT |
612 | /* |
613 | * inode.c | |
614 | */ | |
c435ee34 | 615 | extern int afs_iget5_test(struct inode *, void *); |
bec5eb61 | 616 | extern struct inode *afs_iget_autocell(struct inode *, const char *, int, |
617 | struct key *); | |
00d3b7a4 | 618 | extern struct inode *afs_iget(struct super_block *, struct key *, |
260a9803 DH |
619 | struct afs_fid *, struct afs_file_status *, |
620 | struct afs_callback *); | |
416351f2 | 621 | extern void afs_zap_data(struct afs_vnode *); |
260a9803 | 622 | extern int afs_validate(struct afs_vnode *, struct key *); |
a528d35e | 623 | extern int afs_getattr(const struct path *, struct kstat *, u32, unsigned int); |
31143d5d | 624 | extern int afs_setattr(struct dentry *, struct iattr *); |
b57922d9 | 625 | extern void afs_evict_inode(struct inode *); |
bec5eb61 | 626 | extern int afs_drop_inode(struct inode *); |
1da177e4 LT |
627 | |
628 | /* | |
629 | * main.c | |
630 | */ | |
0ad53eee | 631 | extern struct workqueue_struct *afs_wq; |
f044c884 DH |
632 | |
633 | static inline struct afs_net *afs_d2net(struct dentry *dentry) | |
634 | { | |
635 | return &__afs_net; | |
636 | } | |
637 | ||
638 | static inline struct afs_net *afs_i2net(struct inode *inode) | |
639 | { | |
640 | return &__afs_net; | |
641 | } | |
642 | ||
643 | static inline struct afs_net *afs_v2net(struct afs_vnode *vnode) | |
644 | { | |
645 | return &__afs_net; | |
646 | } | |
647 | ||
648 | static inline struct afs_net *afs_sock2net(struct sock *sk) | |
649 | { | |
650 | return &__afs_net; | |
651 | } | |
652 | ||
653 | static inline struct afs_net *afs_get_net(struct afs_net *net) | |
654 | { | |
655 | return net; | |
656 | } | |
657 | ||
658 | static inline void afs_put_net(struct afs_net *net) | |
659 | { | |
660 | } | |
1da177e4 | 661 | |
08e0e7c8 DH |
662 | /* |
663 | * misc.c | |
664 | */ | |
665 | extern int afs_abort_to_error(u32); | |
666 | ||
1da177e4 LT |
667 | /* |
668 | * mntpt.c | |
669 | */ | |
754661f1 | 670 | extern const struct inode_operations afs_mntpt_inode_operations; |
bec5eb61 | 671 | extern const struct inode_operations afs_autocell_inode_operations; |
4b6f5d20 | 672 | extern const struct file_operations afs_mntpt_file_operations; |
1da177e4 | 673 | |
d18610b0 | 674 | extern struct vfsmount *afs_d_automount(struct path *); |
08e0e7c8 | 675 | extern void afs_mntpt_kill_timer(void); |
1da177e4 | 676 | |
b4db2b35 AB |
677 | /* |
678 | * netdevices.c | |
679 | */ | |
680 | extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool); | |
681 | ||
1da177e4 LT |
682 | /* |
683 | * proc.c | |
684 | */ | |
f044c884 DH |
685 | extern int __net_init afs_proc_init(struct afs_net *); |
686 | extern void __net_exit afs_proc_cleanup(struct afs_net *); | |
687 | extern int afs_proc_cell_setup(struct afs_net *, struct afs_cell *); | |
688 | extern void afs_proc_cell_remove(struct afs_net *, struct afs_cell *); | |
1da177e4 | 689 | |
08e0e7c8 DH |
690 | /* |
691 | * rxrpc.c | |
692 | */ | |
f044c884 | 693 | extern struct workqueue_struct *afs_async_calls; |
8324f0bc | 694 | |
f044c884 DH |
695 | extern int __net_init afs_open_socket(struct afs_net *); |
696 | extern void __net_exit afs_close_socket(struct afs_net *); | |
697 | extern void afs_charge_preallocation(struct work_struct *); | |
341f741f DH |
698 | extern void afs_put_call(struct afs_call *); |
699 | extern int afs_queue_call_work(struct afs_call *); | |
33cd7f2b | 700 | extern long afs_make_call(struct sockaddr_rxrpc *, struct afs_call *, gfp_t, bool); |
f044c884 DH |
701 | extern struct afs_call *afs_alloc_flat_call(struct afs_net *, |
702 | const struct afs_call_type *, | |
08e0e7c8 DH |
703 | size_t, size_t); |
704 | extern void afs_flat_call_destructor(struct afs_call *); | |
08e0e7c8 | 705 | extern void afs_send_empty_reply(struct afs_call *); |
b908fe6b | 706 | extern void afs_send_simple_reply(struct afs_call *, const void *, size_t); |
d001648e | 707 | extern int afs_extract_data(struct afs_call *, void *, size_t, bool); |
08e0e7c8 | 708 | |
d001648e | 709 | static inline int afs_transfer_reply(struct afs_call *call) |
372ee163 | 710 | { |
d001648e | 711 | return afs_extract_data(call, call->buffer, call->reply_max, false); |
372ee163 DH |
712 | } |
713 | ||
00d3b7a4 DH |
714 | /* |
715 | * security.c | |
716 | */ | |
be080a6f | 717 | extern void afs_put_permits(struct afs_permits *); |
00d3b7a4 | 718 | extern void afs_clear_permits(struct afs_vnode *); |
be080a6f | 719 | extern void afs_cache_permit(struct afs_vnode *, struct key *, unsigned int); |
416351f2 | 720 | extern void afs_zap_permits(struct rcu_head *); |
00d3b7a4 | 721 | extern struct key *afs_request_key(struct afs_cell *); |
10556cb2 | 722 | extern int afs_permission(struct inode *, int); |
be080a6f | 723 | extern void __exit afs_clean_up_permit_cache(void); |
00d3b7a4 | 724 | |
08e0e7c8 DH |
725 | /* |
726 | * server.c | |
727 | */ | |
728 | extern spinlock_t afs_server_peer_lock; | |
729 | ||
c435ee34 DH |
730 | static inline struct afs_server *afs_get_server(struct afs_server *server) |
731 | { | |
732 | atomic_inc(&server->usage); | |
733 | return server; | |
734 | } | |
08e0e7c8 | 735 | |
59fa1c4a | 736 | extern void afs_server_timer(struct timer_list *); |
08e0e7c8 | 737 | extern struct afs_server *afs_lookup_server(struct afs_cell *, |
4d9df986 | 738 | struct sockaddr_rxrpc *); |
f044c884 DH |
739 | extern struct afs_server *afs_find_server(struct afs_net *, |
740 | const struct sockaddr_rxrpc *); | |
9ed900b1 | 741 | extern void afs_put_server(struct afs_net *, struct afs_server *); |
f044c884 DH |
742 | extern void afs_reap_server(struct work_struct *); |
743 | extern void __net_exit afs_purge_servers(struct afs_net *); | |
08e0e7c8 | 744 | |
00d3b7a4 DH |
745 | /* |
746 | * super.c | |
747 | */ | |
f044c884 DH |
748 | extern int __init afs_fs_init(void); |
749 | extern void __exit afs_fs_exit(void); | |
00d3b7a4 | 750 | |
08e0e7c8 DH |
751 | /* |
752 | * vlclient.c | |
753 | */ | |
f044c884 | 754 | extern int afs_vl_get_entry_by_name(struct afs_net *, |
4d9df986 | 755 | struct sockaddr_rxrpc *, struct key *, |
00d3b7a4 | 756 | const char *, struct afs_cache_vlocation *, |
56ff9c83 | 757 | bool); |
f044c884 | 758 | extern int afs_vl_get_entry_by_id(struct afs_net *, |
4d9df986 | 759 | struct sockaddr_rxrpc *, struct key *, |
00d3b7a4 | 760 | afs_volid_t, afs_voltype_t, |
56ff9c83 | 761 | struct afs_cache_vlocation *, bool); |
08e0e7c8 DH |
762 | |
763 | /* | |
764 | * vlocation.c | |
765 | */ | |
f044c884 DH |
766 | extern struct workqueue_struct *afs_vlocation_update_worker; |
767 | ||
08e0e7c8 DH |
768 | #define afs_get_vlocation(V) do { atomic_inc(&(V)->usage); } while(0) |
769 | ||
f044c884 DH |
770 | extern struct afs_vlocation *afs_vlocation_lookup(struct afs_net *, |
771 | struct afs_cell *, | |
00d3b7a4 | 772 | struct key *, |
08e0e7c8 | 773 | const char *, size_t); |
f044c884 DH |
774 | extern void afs_put_vlocation(struct afs_net *, struct afs_vlocation *); |
775 | extern void afs_vlocation_updater(struct work_struct *); | |
776 | extern void afs_vlocation_reaper(struct work_struct *); | |
777 | extern void __net_exit afs_vlocation_purge(struct afs_net *); | |
08e0e7c8 DH |
778 | |
779 | /* | |
780 | * vnode.c | |
781 | */ | |
08e0e7c8 DH |
782 | static inline struct afs_vnode *AFS_FS_I(struct inode *inode) |
783 | { | |
784 | return container_of(inode, struct afs_vnode, vfs_inode); | |
785 | } | |
786 | ||
787 | static inline struct inode *AFS_VNODE_TO_I(struct afs_vnode *vnode) | |
788 | { | |
789 | return &vnode->vfs_inode; | |
790 | } | |
791 | ||
260a9803 DH |
792 | extern void afs_vnode_finalise_status_update(struct afs_vnode *, |
793 | struct afs_server *); | |
be080a6f | 794 | extern int afs_vnode_fetch_status(struct afs_vnode *, struct key *, bool); |
00d3b7a4 | 795 | extern int afs_vnode_fetch_data(struct afs_vnode *, struct key *, |
196ee9cd | 796 | struct afs_read *); |
260a9803 DH |
797 | extern int afs_vnode_create(struct afs_vnode *, struct key *, const char *, |
798 | umode_t, struct afs_fid *, struct afs_file_status *, | |
799 | struct afs_callback *, struct afs_server **); | |
800 | extern int afs_vnode_remove(struct afs_vnode *, struct key *, const char *, | |
801 | bool); | |
802 | extern int afs_vnode_link(struct afs_vnode *, struct afs_vnode *, struct key *, | |
803 | const char *); | |
804 | extern int afs_vnode_symlink(struct afs_vnode *, struct key *, const char *, | |
805 | const char *, struct afs_fid *, | |
806 | struct afs_file_status *, struct afs_server **); | |
807 | extern int afs_vnode_rename(struct afs_vnode *, struct afs_vnode *, | |
808 | struct key *, const char *, const char *); | |
31143d5d DH |
809 | extern int afs_vnode_store_data(struct afs_writeback *, pgoff_t, pgoff_t, |
810 | unsigned, unsigned); | |
811 | extern int afs_vnode_setattr(struct afs_vnode *, struct key *, struct iattr *); | |
45222b9e DH |
812 | extern int afs_vnode_get_volume_status(struct afs_vnode *, struct key *, |
813 | struct afs_volume_status *); | |
e8d6c554 DH |
814 | extern int afs_vnode_set_lock(struct afs_vnode *, struct key *, |
815 | afs_lock_type_t); | |
816 | extern int afs_vnode_extend_lock(struct afs_vnode *, struct key *); | |
817 | extern int afs_vnode_release_lock(struct afs_vnode *, struct key *); | |
08e0e7c8 DH |
818 | |
819 | /* | |
820 | * volume.c | |
821 | */ | |
49566f6f DH |
822 | static inline struct afs_volume *afs_get_volume(struct afs_volume *volume) |
823 | { | |
824 | if (volume) | |
825 | atomic_inc(&volume->usage); | |
826 | return volume; | |
827 | } | |
08e0e7c8 | 828 | |
9ed900b1 | 829 | extern void afs_put_volume(struct afs_cell *, struct afs_volume *); |
00d3b7a4 | 830 | extern struct afs_volume *afs_volume_lookup(struct afs_mount_params *); |
08e0e7c8 DH |
831 | extern struct afs_server *afs_volume_pick_fileserver(struct afs_vnode *); |
832 | extern int afs_volume_release_fileserver(struct afs_vnode *, | |
833 | struct afs_server *, int); | |
834 | ||
31143d5d DH |
835 | /* |
836 | * write.c | |
837 | */ | |
838 | extern int afs_set_page_dirty(struct page *); | |
839 | extern void afs_put_writeback(struct afs_writeback *); | |
15b4650e NP |
840 | extern int afs_write_begin(struct file *file, struct address_space *mapping, |
841 | loff_t pos, unsigned len, unsigned flags, | |
842 | struct page **pagep, void **fsdata); | |
843 | extern int afs_write_end(struct file *file, struct address_space *mapping, | |
844 | loff_t pos, unsigned len, unsigned copied, | |
845 | struct page *page, void *fsdata); | |
31143d5d DH |
846 | extern int afs_writepage(struct page *, struct writeback_control *); |
847 | extern int afs_writepages(struct address_space *, struct writeback_control *); | |
31143d5d | 848 | extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *); |
50b5551d | 849 | extern ssize_t afs_file_write(struct kiocb *, struct iov_iter *); |
31143d5d | 850 | extern int afs_writeback_all(struct afs_vnode *); |
58fed94d | 851 | extern int afs_flush(struct file *, fl_owner_t); |
02c24a82 | 852 | extern int afs_fsync(struct file *, loff_t, loff_t, int); |
31143d5d | 853 | |
d3e3b7ea DH |
854 | /* |
855 | * xattr.c | |
856 | */ | |
857 | extern const struct xattr_handler *afs_xattr_handlers[]; | |
858 | extern ssize_t afs_listxattr(struct dentry *, char *, size_t); | |
31143d5d | 859 | |
08e0e7c8 DH |
860 | /*****************************************************************************/ |
861 | /* | |
862 | * debug tracing | |
863 | */ | |
8e8d7f13 DH |
864 | #include <trace/events/afs.h> |
865 | ||
08e0e7c8 DH |
866 | extern unsigned afs_debug; |
867 | ||
868 | #define dbgprintk(FMT,...) \ | |
ad16df84 | 869 | printk("[%-6.6s] "FMT"\n", current->comm ,##__VA_ARGS__) |
08e0e7c8 | 870 | |
530b6412 HH |
871 | #define kenter(FMT,...) dbgprintk("==> %s("FMT")",__func__ ,##__VA_ARGS__) |
872 | #define kleave(FMT,...) dbgprintk("<== %s()"FMT"",__func__ ,##__VA_ARGS__) | |
08e0e7c8 DH |
873 | #define kdebug(FMT,...) dbgprintk(" "FMT ,##__VA_ARGS__) |
874 | ||
875 | ||
876 | #if defined(__KDEBUG) | |
877 | #define _enter(FMT,...) kenter(FMT,##__VA_ARGS__) | |
878 | #define _leave(FMT,...) kleave(FMT,##__VA_ARGS__) | |
879 | #define _debug(FMT,...) kdebug(FMT,##__VA_ARGS__) | |
880 | ||
881 | #elif defined(CONFIG_AFS_DEBUG) | |
882 | #define AFS_DEBUG_KENTER 0x01 | |
883 | #define AFS_DEBUG_KLEAVE 0x02 | |
884 | #define AFS_DEBUG_KDEBUG 0x04 | |
885 | ||
886 | #define _enter(FMT,...) \ | |
887 | do { \ | |
888 | if (unlikely(afs_debug & AFS_DEBUG_KENTER)) \ | |
889 | kenter(FMT,##__VA_ARGS__); \ | |
890 | } while (0) | |
891 | ||
892 | #define _leave(FMT,...) \ | |
893 | do { \ | |
894 | if (unlikely(afs_debug & AFS_DEBUG_KLEAVE)) \ | |
895 | kleave(FMT,##__VA_ARGS__); \ | |
896 | } while (0) | |
897 | ||
898 | #define _debug(FMT,...) \ | |
899 | do { \ | |
900 | if (unlikely(afs_debug & AFS_DEBUG_KDEBUG)) \ | |
901 | kdebug(FMT,##__VA_ARGS__); \ | |
902 | } while (0) | |
903 | ||
904 | #else | |
12fdff3f DH |
905 | #define _enter(FMT,...) no_printk("==> %s("FMT")",__func__ ,##__VA_ARGS__) |
906 | #define _leave(FMT,...) no_printk("<== %s()"FMT"",__func__ ,##__VA_ARGS__) | |
907 | #define _debug(FMT,...) no_printk(" "FMT ,##__VA_ARGS__) | |
08e0e7c8 DH |
908 | #endif |
909 | ||
910 | /* | |
911 | * debug assertion checking | |
912 | */ | |
913 | #if 1 // defined(__KDEBUGALL) | |
914 | ||
915 | #define ASSERT(X) \ | |
916 | do { \ | |
917 | if (unlikely(!(X))) { \ | |
918 | printk(KERN_ERR "\n"); \ | |
919 | printk(KERN_ERR "AFS: Assertion failed\n"); \ | |
920 | BUG(); \ | |
921 | } \ | |
922 | } while(0) | |
923 | ||
924 | #define ASSERTCMP(X, OP, Y) \ | |
925 | do { \ | |
926 | if (unlikely(!((X) OP (Y)))) { \ | |
927 | printk(KERN_ERR "\n"); \ | |
928 | printk(KERN_ERR "AFS: Assertion failed\n"); \ | |
929 | printk(KERN_ERR "%lu " #OP " %lu is false\n", \ | |
930 | (unsigned long)(X), (unsigned long)(Y)); \ | |
931 | printk(KERN_ERR "0x%lx " #OP " 0x%lx is false\n", \ | |
932 | (unsigned long)(X), (unsigned long)(Y)); \ | |
933 | BUG(); \ | |
934 | } \ | |
935 | } while(0) | |
936 | ||
416351f2 DH |
937 | #define ASSERTRANGE(L, OP1, N, OP2, H) \ |
938 | do { \ | |
939 | if (unlikely(!((L) OP1 (N)) || !((N) OP2 (H)))) { \ | |
940 | printk(KERN_ERR "\n"); \ | |
941 | printk(KERN_ERR "AFS: Assertion failed\n"); \ | |
942 | printk(KERN_ERR "%lu "#OP1" %lu "#OP2" %lu is false\n", \ | |
943 | (unsigned long)(L), (unsigned long)(N), \ | |
944 | (unsigned long)(H)); \ | |
945 | printk(KERN_ERR "0x%lx "#OP1" 0x%lx "#OP2" 0x%lx is false\n", \ | |
946 | (unsigned long)(L), (unsigned long)(N), \ | |
947 | (unsigned long)(H)); \ | |
948 | BUG(); \ | |
949 | } \ | |
950 | } while(0) | |
951 | ||
08e0e7c8 DH |
952 | #define ASSERTIF(C, X) \ |
953 | do { \ | |
954 | if (unlikely((C) && !(X))) { \ | |
955 | printk(KERN_ERR "\n"); \ | |
956 | printk(KERN_ERR "AFS: Assertion failed\n"); \ | |
957 | BUG(); \ | |
958 | } \ | |
959 | } while(0) | |
960 | ||
961 | #define ASSERTIFCMP(C, X, OP, Y) \ | |
962 | do { \ | |
963 | if (unlikely((C) && !((X) OP (Y)))) { \ | |
964 | printk(KERN_ERR "\n"); \ | |
965 | printk(KERN_ERR "AFS: Assertion failed\n"); \ | |
966 | printk(KERN_ERR "%lu " #OP " %lu is false\n", \ | |
967 | (unsigned long)(X), (unsigned long)(Y)); \ | |
968 | printk(KERN_ERR "0x%lx " #OP " 0x%lx is false\n", \ | |
969 | (unsigned long)(X), (unsigned long)(Y)); \ | |
970 | BUG(); \ | |
971 | } \ | |
972 | } while(0) | |
973 | ||
974 | #else | |
975 | ||
976 | #define ASSERT(X) \ | |
977 | do { \ | |
978 | } while(0) | |
979 | ||
980 | #define ASSERTCMP(X, OP, Y) \ | |
981 | do { \ | |
982 | } while(0) | |
983 | ||
416351f2 DH |
984 | #define ASSERTRANGE(L, OP1, N, OP2, H) \ |
985 | do { \ | |
986 | } while(0) | |
987 | ||
08e0e7c8 DH |
988 | #define ASSERTIF(C, X) \ |
989 | do { \ | |
990 | } while(0) | |
991 | ||
992 | #define ASSERTIFCMP(C, X, OP, Y) \ | |
993 | do { \ | |
994 | } while(0) | |
995 | ||
996 | #endif /* __KDEBUGALL */ |