blob: df52bf18a2636a3c46efe5a51b114d46af80ba31 [file] [log] [blame]
David Howellsec268152007-04-26 15:49:28 -07001/* internal AFS stuff
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 *
David Howells08e0e7c2007-04-26 15:55:03 -07003 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 * 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070012#include <linux/compiler.h>
13#include <linux/kernel.h>
Tina Ruchandani8a797902017-03-16 16:27:46 +000014#include <linux/ktime.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015#include <linux/fs.h>
16#include <linux/pagemap.h>
David Howells08e0e7c2007-04-26 15:55:03 -070017#include <linux/rxrpc.h>
David Howells00d3b7a2007-04-26 15:57:07 -070018#include <linux/key.h>
Alexey Dobriyane8edc6e2007-05-21 01:22:52 +040019#include <linux/workqueue.h>
Andrew Morton00c541e2007-05-31 00:40:52 -070020#include <linux/sched.h>
Christoph Hellwig80e50be2009-10-01 15:44:27 -070021#include <linux/fscache.h>
Jens Axboee1da0222010-04-22 11:58:18 +020022#include <linux/backing-dev.h>
David Howellsff548772017-02-10 16:34:07 +000023#include <linux/uuid.h>
David Howellsf044c882017-11-02 15:27:45 +000024#include <net/net_namespace.h>
David Howells8324f0b2016-08-30 09:49:29 +010025#include <net/af_rxrpc.h>
Andrew Morton00c541e2007-05-31 00:40:52 -070026
David Howells08e0e7c2007-04-26 15:55:03 -070027#include "afs.h"
28#include "afs_vl.h"
29
30#define AFS_CELL_MAX_ADDRS 15
31
David Howells31143d52007-05-09 02:33:46 -070032struct pagevec;
David Howells08e0e7c2007-04-26 15:55:03 -070033struct afs_call;
34
35typedef 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;
Linus Torvalds1da177e2005-04-16 15:20:36 -070044
David Howells00d3b7a2007-04-26 15:57:07 -070045struct afs_mount_params {
46 bool rwpath; /* T if the parent should be considered R/W */
47 bool force; /* T to force cell type */
wangleibec5eb62010-08-11 09:38:04 +010048 bool autocell; /* T if set auto mount operation */
David Howells00d3b7a2007-04-26 15:57:07 -070049 afs_voltype_t type; /* type of volume requested */
50 int volnamesz; /* size of volume name */
51 const char *volname; /* name of volume to mount */
David Howellsf044c882017-11-02 15:27:45 +000052 struct afs_net *net; /* Network namespace in effect */
David Howells00d3b7a2007-04-26 15:57:07 -070053 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
David Howellsc435ee32017-11-02 15:27:49 +000058struct afs_iget_data {
59 struct afs_fid fid;
60 struct afs_volume *volume; /* volume on which resides */
61};
62
David Howells8e8d7f12017-01-05 10:38:34 +000063enum 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};
David Howellsf044c882017-11-02 15:27:45 +000072
David Howells08e0e7c2007-04-26 15:55:03 -070073/*
David Howells8b2a4642017-11-02 15:27:50 +000074 * List of server addresses.
75 */
76struct afs_addr_list {
77 struct rcu_head rcu; /* Must be first */
78 refcount_t usage;
79 unsigned short nr_addrs;
80 unsigned short index; /* Address currently in use */
81 struct sockaddr_rxrpc addrs[];
82};
83
84/*
David Howells08e0e7c2007-04-26 15:55:03 -070085 * a record of an in-progress RxRPC call
86 */
87struct afs_call {
88 const struct afs_call_type *type; /* type of call */
David Howells08e0e7c2007-04-26 15:55:03 -070089 wait_queue_head_t waitq; /* processes awaiting completion */
David Howells341f7412017-01-05 10:38:36 +000090 struct work_struct async_work; /* async I/O processor */
David Howells08e0e7c2007-04-26 15:55:03 -070091 struct work_struct work; /* actual work processor */
David Howells08e0e7c2007-04-26 15:55:03 -070092 struct rxrpc_call *rxcall; /* RxRPC call handle */
93 struct key *key; /* security for this call */
David Howellsf044c882017-11-02 15:27:45 +000094 struct afs_net *net; /* The network namespace */
David Howellsd0676a12017-11-02 15:27:49 +000095 struct afs_server *cm_server; /* Server affected by incoming CM call */
David Howellsc435ee32017-11-02 15:27:49 +000096 struct afs_server *server; /* Server used by client call */
David Howells08e0e7c2007-04-26 15:55:03 -070097 void *request; /* request data (first part) */
David Howells31143d52007-05-09 02:33:46 -070098 struct address_space *mapping; /* page set */
99 struct afs_writeback *wb; /* writeback being performed */
David Howells08e0e7c2007-04-26 15:55:03 -0700100 void *buffer; /* reply receive buffer */
David Howells97e30432017-11-02 15:27:48 +0000101 void *reply[4]; /* Where to put the reply */
David Howells31143d52007-05-09 02:33:46 -0700102 pgoff_t first; /* first page in mapping to deal with */
103 pgoff_t last; /* last page in mapping to deal with */
David Howellsd0016482016-08-30 20:42:14 +0100104 size_t offset; /* offset into received data store */
David Howells341f7412017-01-05 10:38:36 +0000105 atomic_t usage;
David Howells8e8d7f12017-01-05 10:38:34 +0000106 enum afs_call_state state;
David Howells08e0e7c2007-04-26 15:55:03 -0700107 int error; /* error code */
David Howellsd0016482016-08-30 20:42:14 +0100108 u32 abort_code; /* Remote abort ID or 0 */
David Howells08e0e7c2007-04-26 15:55:03 -0700109 unsigned request_size; /* size of request data */
110 unsigned reply_max; /* maximum size of reply */
David Howells31143d52007-05-09 02:33:46 -0700111 unsigned first_offset; /* offset into mapping[first] */
David Howellsc435ee32017-11-02 15:27:49 +0000112 unsigned int cb_break; /* cb_break + cb_s_break before the call */
Marc Dionnebcd89272017-03-16 16:27:44 +0000113 union {
114 unsigned last_to; /* amount of mapping[last] */
115 unsigned count2; /* count used in unmarshalling */
116 };
David Howells08e0e7c2007-04-26 15:55:03 -0700117 unsigned char unmarshall; /* unmarshalling phase */
118 bool incoming; /* T if incoming call */
David Howells31143d52007-05-09 02:33:46 -0700119 bool send_pages; /* T if data from mapping should be sent */
David Howellsd0016482016-08-30 20:42:14 +0100120 bool need_attention; /* T if RxRPC poked us */
David Howells56ff9c82017-01-05 10:38:36 +0000121 bool async; /* T if asynchronous */
David Howells33cd7f22017-11-02 15:27:48 +0000122 bool ret_reply0; /* T if should return reply[0] on success */
David Howellsa68f4a22017-10-18 11:36:39 +0100123 bool upgrade; /* T to request service upgrade */
David Howells08e0e7c2007-04-26 15:55:03 -0700124 u16 service_id; /* RxRPC service ID to call */
David Howells50a2c952016-10-13 08:27:10 +0100125 u32 operation_ID; /* operation ID for an incoming call */
David Howells08e0e7c2007-04-26 15:55:03 -0700126 u32 count; /* count for use in unmarshalling */
127 __be32 tmp; /* place to extract temporary data */
David Howells31143d52007-05-09 02:33:46 -0700128 afs_dataversion_t store_version; /* updated version expected from store */
David Howells08e0e7c2007-04-26 15:55:03 -0700129};
130
131struct afs_call_type {
David Howells00d3b7a2007-04-26 15:57:07 -0700132 const char *name;
133
David Howells08e0e7c2007-04-26 15:55:03 -0700134 /* deliver request or reply data to an call
135 * - returning an error will cause the call to be aborted
136 */
David Howellsd0016482016-08-30 20:42:14 +0100137 int (*deliver)(struct afs_call *call);
David Howells08e0e7c2007-04-26 15:55:03 -0700138
David Howells08e0e7c2007-04-26 15:55:03 -0700139 /* clean up a call */
140 void (*destructor)(struct afs_call *call);
David Howells341f7412017-01-05 10:38:36 +0000141
142 /* Work function */
143 void (*work)(struct work_struct *work);
David Howells08e0e7c2007-04-26 15:55:03 -0700144};
145
146/*
David Howells196ee9c2017-01-05 10:38:34 +0000147 * Record of an outstanding read operation on a vnode.
148 */
149struct afs_read {
150 loff_t pos; /* Where to start reading */
David Howellse8e581a2017-03-16 16:27:44 +0000151 loff_t len; /* How much we're asking for */
David Howells196ee9c2017-01-05 10:38:34 +0000152 loff_t actual_len; /* How much we're actually getting */
David Howells6a0e3992017-03-16 16:27:46 +0000153 loff_t remain; /* Amount remaining */
David Howells196ee9c2017-01-05 10:38:34 +0000154 atomic_t usage;
David Howells196ee9c2017-01-05 10:38:34 +0000155 unsigned int index; /* Which page we're reading into */
David Howells196ee9c2017-01-05 10:38:34 +0000156 unsigned int nr_pages;
157 void (*page_done)(struct afs_call *, struct afs_read *);
158 struct page *pages[];
159};
160
161/*
David Howells31143d52007-05-09 02:33:46 -0700162 * record of an outstanding writeback on a vnode
163 */
164struct afs_writeback {
165 struct list_head link; /* link in vnode->writebacks */
166 struct work_struct writer; /* work item to perform the writeback */
167 struct afs_vnode *vnode; /* vnode to which this write applies */
168 struct key *key; /* owner of this write */
169 wait_queue_head_t waitq; /* completion and ready wait queue */
170 pgoff_t first; /* first page in batch */
171 pgoff_t point; /* last page in current store op */
172 pgoff_t last; /* last page in batch (inclusive) */
173 unsigned offset_first; /* offset into first page of start of write */
174 unsigned to_last; /* offset into last page of end of write */
175 int num_conflicts; /* count of conflicting writes in list */
176 int usage;
177 bool conflicts; /* T if has dependent conflicts */
178 enum {
179 AFS_WBACK_SYNCING, /* synchronisation being performed */
180 AFS_WBACK_PENDING, /* write pending */
181 AFS_WBACK_CONFLICTING, /* conflicting writes posted */
182 AFS_WBACK_WRITING, /* writing back */
183 AFS_WBACK_COMPLETE /* the writeback record has been unlinked */
184 } state __attribute__((packed));
185};
186
187/*
David Howells08e0e7c2007-04-26 15:55:03 -0700188 * AFS superblock private data
189 * - there's one superblock per volume
190 */
191struct afs_super_info {
David Howellsf044c882017-11-02 15:27:45 +0000192 struct afs_net *net; /* Network namespace */
David Howells49566f62017-11-02 15:27:46 +0000193 struct afs_cell *cell; /* The cell in which the volume resides */
David Howells08e0e7c2007-04-26 15:55:03 -0700194 struct afs_volume *volume; /* volume record */
195 char rwparent; /* T if parent is R/W AFS volume */
196};
197
198static inline struct afs_super_info *AFS_FS_S(struct super_block *sb)
199{
200 return sb->s_fs_info;
201}
202
203extern struct file_system_type afs_fs_type;
204
205/*
David Howellsf044c882017-11-02 15:27:45 +0000206 * AFS network namespace record.
207 */
208struct afs_net {
209 struct afs_uuid uuid;
210 bool live; /* F if this namespace is being removed */
211
212 /* AF_RXRPC I/O stuff */
213 struct socket *socket;
214 struct afs_call *spare_incoming_call;
215 struct work_struct charge_preallocation_work;
216 struct mutex socket_mutex;
217 atomic_t nr_outstanding_calls;
218 atomic_t nr_superblocks;
219
220 /* Cell database */
David Howells989782d2017-11-02 15:27:50 +0000221 struct rb_root cells;
David Howellsf044c882017-11-02 15:27:45 +0000222 struct afs_cell *ws_cell;
David Howells989782d2017-11-02 15:27:50 +0000223 struct work_struct cells_manager;
224 struct timer_list cells_timer;
225 atomic_t cells_outstanding;
226 seqlock_t cells_lock;
David Howellsf044c882017-11-02 15:27:45 +0000227
David Howells989782d2017-11-02 15:27:50 +0000228 spinlock_t proc_cells_lock;
David Howellsf044c882017-11-02 15:27:45 +0000229 struct list_head proc_cells;
230
231 /* Volume location database */
232 struct list_head vl_updates; /* VL records in need-update order */
233 struct list_head vl_graveyard; /* Inactive VL records */
234 struct delayed_work vl_reaper;
235 struct delayed_work vl_updater;
236 spinlock_t vl_updates_lock;
237 spinlock_t vl_graveyard_lock;
238
239 /* File locking renewal management */
240 struct mutex lock_manager_mutex;
241
242 /* Server database */
243 struct rb_root servers; /* Active servers */
244 rwlock_t servers_lock;
245 struct list_head server_graveyard; /* Inactive server LRU list */
246 spinlock_t server_graveyard_lock;
David Howells59fa1c42017-11-02 15:27:45 +0000247 struct timer_list server_timer;
248 struct work_struct server_reaper;
249 atomic_t servers_outstanding;
David Howellsf044c882017-11-02 15:27:45 +0000250
251 /* Misc */
252 struct proc_dir_entry *proc_afs; /* /proc/net/afs directory */
253};
254
255extern struct afs_net __afs_net;// Dummy AFS network namespace; TODO: replace with real netns
256
David Howells989782d2017-11-02 15:27:50 +0000257enum afs_cell_state {
258 AFS_CELL_UNSET,
259 AFS_CELL_ACTIVATING,
260 AFS_CELL_ACTIVE,
261 AFS_CELL_DEACTIVATING,
262 AFS_CELL_INACTIVE,
263 AFS_CELL_FAILED,
264};
265
David Howellsf044c882017-11-02 15:27:45 +0000266/*
David Howells08e0e7c2007-04-26 15:55:03 -0700267 * AFS cell record
268 */
269struct afs_cell {
David Howells989782d2017-11-02 15:27:50 +0000270 union {
271 struct rcu_head rcu;
272 struct rb_node net_node; /* Node in net->cells */
273 };
274 struct afs_net *net;
David Howells00d3b7a2007-04-26 15:57:07 -0700275 struct key *anonymous_key; /* anonymous user key for this cell */
David Howells989782d2017-11-02 15:27:50 +0000276 struct work_struct manager; /* Manager for init/deinit/dns */
David Howells08e0e7c2007-04-26 15:55:03 -0700277 struct list_head proc_link; /* /proc cell list link */
David Howells9b3f26c2009-04-03 16:42:41 +0100278#ifdef CONFIG_AFS_FSCACHE
279 struct fscache_cookie *cache; /* caching cookie */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280#endif
281
David Howells08e0e7c2007-04-26 15:55:03 -0700282 /* server record management */
283 rwlock_t servers_lock; /* active server list lock */
284 struct list_head servers; /* active server list */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285
David Howells08e0e7c2007-04-26 15:55:03 -0700286 /* volume location record management */
287 struct rw_semaphore vl_sem; /* volume management serialisation semaphore */
288 struct list_head vl_list; /* cell's active VL record list */
David Howells989782d2017-11-02 15:27:50 +0000289 time64_t dns_expiry; /* Time AFSDB/SRV record expires */
290 time64_t last_inactive; /* Time of last drop of usage count */
291 atomic_t usage;
292 unsigned long flags;
293#define AFS_CELL_FL_NOT_READY 0 /* The cell record is not ready for use */
294#define AFS_CELL_FL_NO_GC 1 /* The cell was added manually, don't auto-gc */
295#define AFS_CELL_FL_NOT_FOUND 2 /* Permanent DNS error */
296#define AFS_CELL_FL_DNS_FAIL 3 /* Failed to access DNS */
David Howells8b2a4642017-11-02 15:27:50 +0000297#define AFS_CELL_FL_NO_LOOKUP_YET 4 /* Not completed first DNS lookup yet */
David Howells989782d2017-11-02 15:27:50 +0000298 enum afs_cell_state state;
299 short error;
300
David Howells08e0e7c2007-04-26 15:55:03 -0700301 spinlock_t vl_lock; /* vl_list lock */
David Howells989782d2017-11-02 15:27:50 +0000302
303 /* VLDB server list. */
David Howells8b2a4642017-11-02 15:27:50 +0000304 rwlock_t vl_addrs_lock; /* Lock on vl_addrs */
305 struct afs_addr_list __rcu *vl_addrs; /* List of VL servers */
David Howells989782d2017-11-02 15:27:50 +0000306 u8 name_len; /* Length of name */
307 char name[64 + 1]; /* Cell name, case-flattened and NUL-padded */
David Howells08e0e7c2007-04-26 15:55:03 -0700308};
309
310/*
311 * entry in the cached volume location catalogue
312 */
313struct afs_cache_vlocation {
David Howells00d3b7a2007-04-26 15:57:07 -0700314 /* volume name (lowercase, padded with NULs) */
315 uint8_t name[AFS_MAXVOLNAME + 1];
316
David Howells08e0e7c2007-04-26 15:55:03 -0700317 uint8_t nservers; /* number of entries used in servers[] */
318 uint8_t vidmask; /* voltype mask for vid[] */
319 uint8_t srvtmask[8]; /* voltype masks for servers[] */
320#define AFS_VOL_VTM_RW 0x01 /* R/W version of the volume is available (on this server) */
321#define AFS_VOL_VTM_RO 0x02 /* R/O version of the volume is available (on this server) */
322#define AFS_VOL_VTM_BAK 0x04 /* backup version of the volume is available (on this server) */
323
324 afs_volid_t vid[3]; /* volume IDs for R/W, R/O and Bak volumes */
David Howells4d9df982017-11-02 15:27:47 +0000325 struct sockaddr_rxrpc servers[8]; /* fileserver addresses */
David Howells08e0e7c2007-04-26 15:55:03 -0700326 time_t rtime; /* last retrieval time */
327};
328
329/*
David Howells08e0e7c2007-04-26 15:55:03 -0700330 * AFS volume location record
331 */
332struct afs_vlocation {
333 atomic_t usage;
Tina Ruchandani8a797902017-03-16 16:27:46 +0000334 time64_t time_of_death; /* time at which put reduced usage to 0 */
David Howells08e0e7c2007-04-26 15:55:03 -0700335 struct list_head link; /* link in cell volume location list */
336 struct list_head grave; /* link in master graveyard list */
337 struct list_head update; /* link in master update list */
338 struct afs_cell *cell; /* cell to which volume belongs */
David Howells08e0e7c2007-04-26 15:55:03 -0700339 struct afs_cache_vlocation vldb; /* volume information DB record */
340 struct afs_volume *vols[3]; /* volume access record pointer (index by type) */
341 wait_queue_head_t waitq; /* status change waitqueue */
Tina Ruchandani8a797902017-03-16 16:27:46 +0000342 time64_t update_at; /* time at which record should be updated */
David S. Miller39bf0942007-04-26 20:39:14 -0700343 spinlock_t lock; /* access lock */
David Howells08e0e7c2007-04-26 15:55:03 -0700344 afs_vlocation_state_t state; /* volume location state */
345 unsigned short upd_rej_cnt; /* ENOMEDIUM count during update */
346 unsigned short upd_busy_cnt; /* EBUSY count during update */
347 bool valid; /* T if valid */
348};
349
350/*
351 * AFS fileserver record
352 */
353struct afs_server {
354 atomic_t usage;
Tina Ruchandani8a797902017-03-16 16:27:46 +0000355 time64_t time_of_death; /* time at which put reduced usage to 0 */
David Howells8b2a4642017-11-02 15:27:50 +0000356 struct afs_addr_list __rcu *addrs; /* List of addresses for this server */
David Howells9ed900b2017-11-02 15:27:46 +0000357 struct afs_net *net; /* Network namespace in which the server resides */
David Howells08e0e7c2007-04-26 15:55:03 -0700358 struct afs_cell *cell; /* cell in which server resides */
359 struct list_head link; /* link in cell's server list */
360 struct list_head grave; /* link in master graveyard list */
David Howellsc435ee32017-11-02 15:27:49 +0000361
David Howells08e0e7c2007-04-26 15:55:03 -0700362 struct rb_node master_rb; /* link in master by-addr tree */
363 struct rw_semaphore sem; /* access lock */
David Howellsc435ee32017-11-02 15:27:49 +0000364 unsigned long flags;
365#define AFS_SERVER_NEW 0 /* New server, don't inc cb_s_break */
David Howells08e0e7c2007-04-26 15:55:03 -0700366
367 /* file service access */
David Howells08e0e7c2007-04-26 15:55:03 -0700368 int fs_state; /* 0 or reason FS currently marked dead (-errno) */
David Howellsc435ee32017-11-02 15:27:49 +0000369 spinlock_t fs_lock; /* access lock */
David Howells08e0e7c2007-04-26 15:55:03 -0700370
371 /* callback promise management */
David Howellsc435ee32017-11-02 15:27:49 +0000372 struct list_head cb_interests; /* List of superblocks using this server */
373 unsigned cb_s_break; /* Break-everything counter. */
374 rwlock_t cb_break_lock; /* Volume finding lock */
375};
376
377/*
378 * Interest by a superblock on a server.
379 */
380struct afs_cb_interest {
381 struct list_head cb_link; /* Link in server->cb_interests */
382 struct afs_server *server; /* Server on which this interest resides */
383 struct super_block *sb; /* Superblock on which inodes reside */
384 afs_volid_t vid; /* Volume ID to match */
385 refcount_t usage;
David Howells08e0e7c2007-04-26 15:55:03 -0700386};
387
388/*
389 * AFS volume access record
390 */
391struct afs_volume {
392 atomic_t usage;
393 struct afs_cell *cell; /* cell to which belongs (unrefd ptr) */
394 struct afs_vlocation *vlocation; /* volume location */
David Howells9b3f26c2009-04-03 16:42:41 +0100395#ifdef CONFIG_AFS_FSCACHE
396 struct fscache_cookie *cache; /* caching cookie */
David Howells08e0e7c2007-04-26 15:55:03 -0700397#endif
398 afs_volid_t vid; /* volume ID */
399 afs_voltype_t type; /* type of volume */
400 char type_force; /* force volume type (suppress R/O -> R/W) */
401 unsigned short nservers; /* number of server slots filled */
402 unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */
403 struct afs_server *servers[8]; /* servers on which volume resides (ordered) */
David Howellsc435ee32017-11-02 15:27:49 +0000404 struct afs_cb_interest *cb_interests[8]; /* Interests on servers for callbacks */
David Howells08e0e7c2007-04-26 15:55:03 -0700405 struct rw_semaphore server_sem; /* lock for accessing current server */
406};
407
408/*
409 * vnode catalogue entry
410 */
411struct afs_cache_vnode {
412 afs_vnodeid_t vnode_id; /* vnode ID */
413 unsigned vnode_unique; /* vnode ID uniquifier */
414 afs_dataversion_t data_version; /* data version */
415};
416
417/*
418 * AFS inode private data
419 */
420struct afs_vnode {
421 struct inode vfs_inode; /* the VFS's inode record */
422
423 struct afs_volume *volume; /* volume on which vnode resides */
David Howells08e0e7c2007-04-26 15:55:03 -0700424 struct afs_fid fid; /* the file identifier for this inode */
425 struct afs_file_status status; /* AFS status info for this file */
David Howells9b3f26c2009-04-03 16:42:41 +0100426#ifdef CONFIG_AFS_FSCACHE
427 struct fscache_cookie *cache; /* caching cookie */
David Howells08e0e7c2007-04-26 15:55:03 -0700428#endif
David Howellsbe080a62017-11-02 15:27:49 +0000429 struct afs_permits *permit_cache; /* cache of permits so far obtained */
David Howells260a9802007-04-26 15:59:35 -0700430 struct mutex validate_lock; /* lock for validating this vnode */
David Howells08e0e7c2007-04-26 15:55:03 -0700431 wait_queue_head_t update_waitq; /* status fetch waitqueue */
David Howells260a9802007-04-26 15:59:35 -0700432 int update_cnt; /* number of outstanding ops that will update the
David Howells08e0e7c2007-04-26 15:55:03 -0700433 * status */
David Howells31143d52007-05-09 02:33:46 -0700434 spinlock_t writeback_lock; /* lock for writebacks */
David Howells08e0e7c2007-04-26 15:55:03 -0700435 spinlock_t lock; /* waitqueue/flags lock */
436 unsigned long flags;
David Howellsc435ee32017-11-02 15:27:49 +0000437#define AFS_VNODE_CB_PROMISED 0 /* Set if vnode has a callback promise */
David Howells260a9802007-04-26 15:59:35 -0700438#define AFS_VNODE_UNSET 1 /* set if vnode attributes not yet set */
David Howellsc435ee32017-11-02 15:27:49 +0000439#define AFS_VNODE_DIR_MODIFIED 2 /* set if dir vnode's data modified */
David Howells08e0e7c2007-04-26 15:55:03 -0700440#define AFS_VNODE_ZAP_DATA 3 /* set if vnode's data should be invalidated */
441#define AFS_VNODE_DELETED 4 /* set if vnode deleted on server */
442#define AFS_VNODE_MOUNTPOINT 5 /* set if vnode is a mountpoint symlink */
David Howellse8d6c552007-07-15 23:40:12 -0700443#define AFS_VNODE_LOCKING 6 /* set if waiting for lock on vnode */
444#define AFS_VNODE_READLOCKED 7 /* set if vnode is read-locked on the server */
445#define AFS_VNODE_WRITELOCKED 8 /* set if vnode is write-locked on the server */
446#define AFS_VNODE_UNLOCKING 9 /* set if vnode is being unlocked on the server */
wangleibec5eb62010-08-11 09:38:04 +0100447#define AFS_VNODE_AUTOCELL 10 /* set if Vnode is an auto mount point */
448#define AFS_VNODE_PSEUDODIR 11 /* set if Vnode is a pseudo directory */
David Howells08e0e7c2007-04-26 15:55:03 -0700449
David Howells31143d52007-05-09 02:33:46 -0700450 struct list_head writebacks; /* alterations in pagecache that need writing */
David Howellse8d6c552007-07-15 23:40:12 -0700451 struct list_head pending_locks; /* locks waiting to be granted */
452 struct list_head granted_locks; /* locks granted on this file */
453 struct delayed_work lock_work; /* work to be done in locking */
454 struct key *unlock_key; /* key to be used in unlocking */
David Howells31143d52007-05-09 02:33:46 -0700455
David Howells08e0e7c2007-04-26 15:55:03 -0700456 /* outstanding callback notification on this file */
David Howellsc435ee32017-11-02 15:27:49 +0000457 struct afs_cb_interest *cb_interest; /* Server on which this resides */
458 unsigned int cb_s_break; /* Mass break counter on ->server */
459 unsigned int cb_break; /* Break counter on vnode */
460 seqlock_t cb_lock; /* Lock for ->cb_interest, ->status, ->cb_*break */
461
462 time64_t cb_expires_at; /* time at which callback expires */
David Howells08e0e7c2007-04-26 15:55:03 -0700463 unsigned cb_version; /* callback version */
David Howells08e0e7c2007-04-26 15:55:03 -0700464 afs_callback_type_t cb_type; /* type of callback */
David Howells08e0e7c2007-04-26 15:55:03 -0700465};
466
David Howells00d3b7a2007-04-26 15:57:07 -0700467/*
468 * cached security record for one user's attempt to access a vnode
469 */
470struct afs_permit {
471 struct key *key; /* RxRPC ticket holding a security context */
David Howellsbe080a62017-11-02 15:27:49 +0000472 afs_access_t access; /* CallerAccess value for this key */
David Howells00d3b7a2007-04-26 15:57:07 -0700473};
474
475/*
David Howellsbe080a62017-11-02 15:27:49 +0000476 * Immutable cache of CallerAccess records from attempts to access vnodes.
477 * These may be shared between multiple vnodes.
David Howells00d3b7a2007-04-26 15:57:07 -0700478 */
479struct afs_permits {
David Howellsbe080a62017-11-02 15:27:49 +0000480 struct rcu_head rcu;
481 struct hlist_node hash_node; /* Link in hash */
482 unsigned long h; /* Hash value for this permit list */
483 refcount_t usage;
484 unsigned short nr_permits; /* Number of records */
485 bool invalidated; /* Invalidated due to key change */
486 struct afs_permit permits[]; /* List of permits sorted by key pointer */
David Howells00d3b7a2007-04-26 15:57:07 -0700487};
488
David Howellsb908fe62007-04-26 15:58:17 -0700489/*
490 * record of one of a system's set of network interfaces
491 */
492struct afs_interface {
David Howellsb908fe62007-04-26 15:58:17 -0700493 struct in_addr address; /* IPv4 address bound to interface */
494 struct in_addr netmask; /* netmask applied to address */
495 unsigned mtu; /* MTU of interface */
496};
497
David Howells8b2a4642017-11-02 15:27:50 +0000498/*
499 * Cursor for iterating over a server's address list.
500 */
501struct afs_addr_cursor {
502 struct afs_addr_list *alist; /* Current address list (pins ref) */
503 struct sockaddr_rxrpc *addr;
504 unsigned short start; /* Starting point in alist->addrs[] */
505 unsigned short index; /* Wrapping offset from start to current addr */
506 short error;
507 bool begun; /* T if we've begun iteration */
508 bool responded; /* T if the current address responded */
509};
510
511/*
512 * Cursor for iterating over a set of fileservers.
513 */
514struct afs_fs_cursor {
515 struct afs_addr_cursor ac;
516 struct afs_server *server; /* Current server (pins ref) */
517};
518
David Howells08e0e7c2007-04-26 15:55:03 -0700519/*****************************************************************************/
520/*
David Howells8b2a4642017-11-02 15:27:50 +0000521 * addr_list.c
522 */
523static inline struct afs_addr_list *afs_get_addrlist(struct afs_addr_list *alist)
524{
525 if (alist)
526 refcount_inc(&alist->usage);
527 return alist;
528}
529extern struct afs_addr_list *afs_alloc_addrlist(unsigned int,
530 unsigned short,
531 unsigned short);
532extern void afs_put_addrlist(struct afs_addr_list *);
533extern struct afs_addr_list *afs_parse_text_addrs(const char *, size_t, char,
534 unsigned short, unsigned short);
535extern struct afs_addr_list *afs_dns_query(struct afs_cell *, time64_t *);
536extern bool afs_iterate_addresses(struct afs_addr_cursor *);
537extern int afs_end_cursor(struct afs_addr_cursor *);
538extern int afs_set_vl_cursor(struct afs_addr_cursor *, struct afs_cell *);
539
540/*
David Howells9b3f26c2009-04-03 16:42:41 +0100541 * cache.c
542 */
543#ifdef CONFIG_AFS_FSCACHE
544extern struct fscache_netfs afs_cache_netfs;
545extern struct fscache_cookie_def afs_cell_cache_index_def;
David Howells9b3f26c2009-04-03 16:42:41 +0100546extern struct fscache_cookie_def afs_volume_cache_index_def;
547extern struct fscache_cookie_def afs_vnode_cache_index_def;
548#else
549#define afs_cell_cache_index_def (*(struct fscache_cookie_def *) NULL)
David Howells9b3f26c2009-04-03 16:42:41 +0100550#define afs_volume_cache_index_def (*(struct fscache_cookie_def *) NULL)
551#define afs_vnode_cache_index_def (*(struct fscache_cookie_def *) NULL)
552#endif
553
554/*
David Howells08e0e7c2007-04-26 15:55:03 -0700555 * callback.c
556 */
557extern void afs_init_callback_state(struct afs_server *);
David Howellsc435ee32017-11-02 15:27:49 +0000558extern void afs_break_callback(struct afs_vnode *);
559extern void afs_break_callbacks(struct afs_server *, size_t,struct afs_callback[]);
560
561extern int afs_register_server_cb_interest(struct afs_vnode *, struct afs_cb_interest **,
562 struct afs_server *);
563extern void afs_put_cb_interest(struct afs_net *, struct afs_cb_interest *);
564extern void afs_clear_callback_interests(struct afs_net *, struct afs_volume *);
565
566static inline struct afs_cb_interest *afs_get_cb_interest(struct afs_cb_interest *cbi)
567{
568 refcount_inc(&cbi->usage);
569 return cbi;
570}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571
572/*
573 * cell.c
574 */
David Howells989782d2017-11-02 15:27:50 +0000575extern int afs_cell_init(struct afs_net *, const char *);
576extern struct afs_cell *afs_lookup_cell_rcu(struct afs_net *, const char *, unsigned);
577extern struct afs_cell *afs_lookup_cell(struct afs_net *, const char *, unsigned,
578 const char *, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000579extern struct afs_cell *afs_get_cell(struct afs_cell *);
David Howells9ed900b2017-11-02 15:27:46 +0000580extern void afs_put_cell(struct afs_net *, struct afs_cell *);
David Howells989782d2017-11-02 15:27:50 +0000581extern void afs_manage_cells(struct work_struct *);
582extern void afs_cells_timer(struct timer_list *);
David Howellsf044c882017-11-02 15:27:45 +0000583extern void __net_exit afs_cell_purge(struct afs_net *);
David Howells08e0e7c2007-04-26 15:55:03 -0700584
585/*
586 * cmservice.c
587 */
588extern bool afs_cm_incoming_call(struct afs_call *);
589
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590/*
591 * dir.c
592 */
Arjan van de Ven754661f2007-02-12 00:55:38 -0800593extern const struct inode_operations afs_dir_inode_operations;
Al Virod61dcce2011-01-12 20:04:20 -0500594extern const struct dentry_operations afs_fs_dentry_operations;
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -0800595extern const struct file_operations afs_dir_file_operations;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596
597/*
598 * file.c
599 */
Christoph Hellwigf5e54d62006-06-28 04:26:44 -0700600extern const struct address_space_operations afs_fs_aops;
Arjan van de Ven754661f2007-02-12 00:55:38 -0800601extern const struct inode_operations afs_file_inode_operations;
David Howells00d3b7a2007-04-26 15:57:07 -0700602extern const struct file_operations afs_file_operations;
603
604extern int afs_open(struct inode *, struct file *);
605extern int afs_release(struct inode *, struct file *);
Al Virof6d335c2010-05-21 15:27:09 +0100606extern int afs_page_filler(void *, struct page *);
David Howells196ee9c2017-01-05 10:38:34 +0000607extern void afs_put_read(struct afs_read *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609/*
David Howellse8d6c552007-07-15 23:40:12 -0700610 * flock.c
611 */
David Howellsf044c882017-11-02 15:27:45 +0000612extern struct workqueue_struct *afs_lock_manager;
613
David Howellse8d6c552007-07-15 23:40:12 -0700614extern void afs_lock_work(struct work_struct *);
615extern void afs_lock_may_be_available(struct afs_vnode *);
616extern int afs_lock(struct file *, int, struct file_lock *);
617extern int afs_flock(struct file *, int, struct file_lock *);
618
619/*
David Howells08e0e7c2007-04-26 15:55:03 -0700620 * fsclient.c
621 */
David Howells8b2a4642017-11-02 15:27:50 +0000622extern int afs_fs_fetch_file_status(struct afs_fs_cursor *, struct key *,
David Howells00d3b7a2007-04-26 15:57:07 -0700623 struct afs_vnode *, struct afs_volsync *,
David Howells56ff9c82017-01-05 10:38:36 +0000624 bool);
David Howellsf044c882017-11-02 15:27:45 +0000625extern int afs_fs_give_up_callbacks(struct afs_net *, struct afs_server *, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000626extern int afs_fs_fetch_data(struct afs_fs_cursor *, struct key *,
David Howells56ff9c82017-01-05 10:38:36 +0000627 struct afs_vnode *, struct afs_read *, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000628extern int afs_fs_create(struct afs_fs_cursor *, struct key *,
David Howells260a9802007-04-26 15:59:35 -0700629 struct afs_vnode *, const char *, umode_t,
630 struct afs_fid *, struct afs_file_status *,
David Howells56ff9c82017-01-05 10:38:36 +0000631 struct afs_callback *, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000632extern int afs_fs_remove(struct afs_fs_cursor *, struct key *,
David Howells56ff9c82017-01-05 10:38:36 +0000633 struct afs_vnode *, const char *, bool, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000634extern int afs_fs_link(struct afs_fs_cursor *, struct key *, struct afs_vnode *,
David Howells56ff9c82017-01-05 10:38:36 +0000635 struct afs_vnode *, const char *, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000636extern int afs_fs_symlink(struct afs_fs_cursor *, struct key *,
David Howells260a9802007-04-26 15:59:35 -0700637 struct afs_vnode *, const char *, const char *,
David Howells56ff9c82017-01-05 10:38:36 +0000638 struct afs_fid *, struct afs_file_status *, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000639extern int afs_fs_rename(struct afs_fs_cursor *, struct key *,
David Howells260a9802007-04-26 15:59:35 -0700640 struct afs_vnode *, const char *,
David Howells56ff9c82017-01-05 10:38:36 +0000641 struct afs_vnode *, const char *, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000642extern int afs_fs_store_data(struct afs_fs_cursor *, struct afs_writeback *,
David Howells56ff9c82017-01-05 10:38:36 +0000643 pgoff_t, pgoff_t, unsigned, unsigned, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000644extern int afs_fs_setattr(struct afs_fs_cursor *, struct key *,
David Howells56ff9c82017-01-05 10:38:36 +0000645 struct afs_vnode *, struct iattr *, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000646extern int afs_fs_get_volume_status(struct afs_fs_cursor *, struct key *,
David Howells45222b92007-05-10 22:22:20 -0700647 struct afs_vnode *,
David Howells56ff9c82017-01-05 10:38:36 +0000648 struct afs_volume_status *, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000649extern int afs_fs_set_lock(struct afs_fs_cursor *, struct key *,
David Howells56ff9c82017-01-05 10:38:36 +0000650 struct afs_vnode *, afs_lock_type_t, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000651extern int afs_fs_extend_lock(struct afs_fs_cursor *, struct key *,
David Howells56ff9c82017-01-05 10:38:36 +0000652 struct afs_vnode *, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000653extern int afs_fs_release_lock(struct afs_fs_cursor *, struct key *,
David Howells56ff9c82017-01-05 10:38:36 +0000654 struct afs_vnode *, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000655extern int afs_fs_give_up_all_callbacks(struct afs_server *, struct afs_addr_cursor *,
656 struct key *, bool);
David Howells08e0e7c2007-04-26 15:55:03 -0700657
658/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659 * inode.c
660 */
David Howellsc435ee32017-11-02 15:27:49 +0000661extern int afs_iget5_test(struct inode *, void *);
wangleibec5eb62010-08-11 09:38:04 +0100662extern struct inode *afs_iget_autocell(struct inode *, const char *, int,
663 struct key *);
David Howells00d3b7a2007-04-26 15:57:07 -0700664extern struct inode *afs_iget(struct super_block *, struct key *,
David Howells260a9802007-04-26 15:59:35 -0700665 struct afs_fid *, struct afs_file_status *,
666 struct afs_callback *);
David Howells416351f2007-05-09 02:33:45 -0700667extern void afs_zap_data(struct afs_vnode *);
David Howells260a9802007-04-26 15:59:35 -0700668extern int afs_validate(struct afs_vnode *, struct key *);
David Howellsa528d352017-01-31 16:46:22 +0000669extern int afs_getattr(const struct path *, struct kstat *, u32, unsigned int);
David Howells31143d52007-05-09 02:33:46 -0700670extern int afs_setattr(struct dentry *, struct iattr *);
Al Virob57922d2010-06-07 14:34:48 -0400671extern void afs_evict_inode(struct inode *);
wangleibec5eb62010-08-11 09:38:04 +0100672extern int afs_drop_inode(struct inode *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673
674/*
675 * main.c
676 */
Tejun Heo0ad53ee2011-01-14 15:56:37 +0000677extern struct workqueue_struct *afs_wq;
David Howellsf044c882017-11-02 15:27:45 +0000678
679static inline struct afs_net *afs_d2net(struct dentry *dentry)
680{
681 return &__afs_net;
682}
683
684static inline struct afs_net *afs_i2net(struct inode *inode)
685{
686 return &__afs_net;
687}
688
689static inline struct afs_net *afs_v2net(struct afs_vnode *vnode)
690{
691 return &__afs_net;
692}
693
694static inline struct afs_net *afs_sock2net(struct sock *sk)
695{
696 return &__afs_net;
697}
698
699static inline struct afs_net *afs_get_net(struct afs_net *net)
700{
701 return net;
702}
703
704static inline void afs_put_net(struct afs_net *net)
705{
706}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707
708/*
David Howells08e0e7c2007-04-26 15:55:03 -0700709 * misc.c
710 */
711extern int afs_abort_to_error(u32);
712
713/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 * mntpt.c
715 */
Arjan van de Ven754661f2007-02-12 00:55:38 -0800716extern const struct inode_operations afs_mntpt_inode_operations;
wangleibec5eb62010-08-11 09:38:04 +0100717extern const struct inode_operations afs_autocell_inode_operations;
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -0800718extern const struct file_operations afs_mntpt_file_operations;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719
David Howellsd18610b2011-01-14 19:04:05 +0000720extern struct vfsmount *afs_d_automount(struct path *);
David Howells08e0e7c2007-04-26 15:55:03 -0700721extern void afs_mntpt_kill_timer(void);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722
723/*
Arnd Bergmannb4db2b32017-02-10 16:34:07 +0000724 * netdevices.c
725 */
726extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool);
727
728/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 * proc.c
730 */
David Howellsf044c882017-11-02 15:27:45 +0000731extern int __net_init afs_proc_init(struct afs_net *);
732extern void __net_exit afs_proc_cleanup(struct afs_net *);
733extern int afs_proc_cell_setup(struct afs_net *, struct afs_cell *);
734extern void afs_proc_cell_remove(struct afs_net *, struct afs_cell *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735
David Howells08e0e7c2007-04-26 15:55:03 -0700736/*
737 * rxrpc.c
738 */
David Howellsf044c882017-11-02 15:27:45 +0000739extern struct workqueue_struct *afs_async_calls;
David Howells8324f0b2016-08-30 09:49:29 +0100740
David Howellsf044c882017-11-02 15:27:45 +0000741extern int __net_init afs_open_socket(struct afs_net *);
742extern void __net_exit afs_close_socket(struct afs_net *);
743extern void afs_charge_preallocation(struct work_struct *);
David Howells341f7412017-01-05 10:38:36 +0000744extern void afs_put_call(struct afs_call *);
745extern int afs_queue_call_work(struct afs_call *);
David Howells8b2a4642017-11-02 15:27:50 +0000746extern long afs_make_call(struct afs_addr_cursor *, struct afs_call *, gfp_t, bool);
David Howellsf044c882017-11-02 15:27:45 +0000747extern struct afs_call *afs_alloc_flat_call(struct afs_net *,
748 const struct afs_call_type *,
David Howells08e0e7c2007-04-26 15:55:03 -0700749 size_t, size_t);
750extern void afs_flat_call_destructor(struct afs_call *);
David Howells08e0e7c2007-04-26 15:55:03 -0700751extern void afs_send_empty_reply(struct afs_call *);
David Howellsb908fe62007-04-26 15:58:17 -0700752extern void afs_send_simple_reply(struct afs_call *, const void *, size_t);
David Howellsd0016482016-08-30 20:42:14 +0100753extern int afs_extract_data(struct afs_call *, void *, size_t, bool);
David Howells08e0e7c2007-04-26 15:55:03 -0700754
David Howellsd0016482016-08-30 20:42:14 +0100755static inline int afs_transfer_reply(struct afs_call *call)
David Howells372ee162016-08-03 14:11:40 +0100756{
David Howellsd0016482016-08-30 20:42:14 +0100757 return afs_extract_data(call, call->buffer, call->reply_max, false);
David Howells372ee162016-08-03 14:11:40 +0100758}
759
David Howells08e0e7c2007-04-26 15:55:03 -0700760/*
David Howells00d3b7a2007-04-26 15:57:07 -0700761 * security.c
762 */
David Howellsbe080a62017-11-02 15:27:49 +0000763extern void afs_put_permits(struct afs_permits *);
David Howells00d3b7a2007-04-26 15:57:07 -0700764extern void afs_clear_permits(struct afs_vnode *);
David Howellsbe080a62017-11-02 15:27:49 +0000765extern void afs_cache_permit(struct afs_vnode *, struct key *, unsigned int);
David Howells416351f2007-05-09 02:33:45 -0700766extern void afs_zap_permits(struct rcu_head *);
David Howells00d3b7a2007-04-26 15:57:07 -0700767extern struct key *afs_request_key(struct afs_cell *);
Al Viro10556cb2011-06-20 19:28:19 -0400768extern int afs_permission(struct inode *, int);
David Howellsbe080a62017-11-02 15:27:49 +0000769extern void __exit afs_clean_up_permit_cache(void);
David Howells00d3b7a2007-04-26 15:57:07 -0700770
771/*
David Howells08e0e7c2007-04-26 15:55:03 -0700772 * server.c
773 */
774extern spinlock_t afs_server_peer_lock;
775
David Howellsc435ee32017-11-02 15:27:49 +0000776static inline struct afs_server *afs_get_server(struct afs_server *server)
777{
778 atomic_inc(&server->usage);
779 return server;
780}
David Howells08e0e7c2007-04-26 15:55:03 -0700781
David Howells59fa1c42017-11-02 15:27:45 +0000782extern void afs_server_timer(struct timer_list *);
David Howells08e0e7c2007-04-26 15:55:03 -0700783extern struct afs_server *afs_lookup_server(struct afs_cell *,
David Howells4d9df982017-11-02 15:27:47 +0000784 struct sockaddr_rxrpc *);
David Howellsf044c882017-11-02 15:27:45 +0000785extern struct afs_server *afs_find_server(struct afs_net *,
786 const struct sockaddr_rxrpc *);
David Howells9ed900b2017-11-02 15:27:46 +0000787extern void afs_put_server(struct afs_net *, struct afs_server *);
David Howellsf044c882017-11-02 15:27:45 +0000788extern void afs_reap_server(struct work_struct *);
789extern void __net_exit afs_purge_servers(struct afs_net *);
David Howells08e0e7c2007-04-26 15:55:03 -0700790
791/*
David Howells00d3b7a2007-04-26 15:57:07 -0700792 * super.c
793 */
David Howellsf044c882017-11-02 15:27:45 +0000794extern int __init afs_fs_init(void);
795extern void __exit afs_fs_exit(void);
David Howells00d3b7a2007-04-26 15:57:07 -0700796
797/*
David Howells08e0e7c2007-04-26 15:55:03 -0700798 * vlclient.c
799 */
David Howells8b2a4642017-11-02 15:27:50 +0000800extern int afs_vl_get_entry_by_name(struct afs_net *, struct afs_addr_cursor *,
801 struct key *, const char *,
802 struct afs_cache_vlocation *, bool);
803extern int afs_vl_get_entry_by_id(struct afs_net *, struct afs_addr_cursor *,
804 struct key *, afs_volid_t, afs_voltype_t,
David Howells56ff9c82017-01-05 10:38:36 +0000805 struct afs_cache_vlocation *, bool);
David Howells08e0e7c2007-04-26 15:55:03 -0700806
807/*
808 * vlocation.c
809 */
David Howellsf044c882017-11-02 15:27:45 +0000810extern struct workqueue_struct *afs_vlocation_update_worker;
811
David Howells08e0e7c2007-04-26 15:55:03 -0700812#define afs_get_vlocation(V) do { atomic_inc(&(V)->usage); } while(0)
813
David Howellsf044c882017-11-02 15:27:45 +0000814extern struct afs_vlocation *afs_vlocation_lookup(struct afs_net *,
815 struct afs_cell *,
David Howells00d3b7a2007-04-26 15:57:07 -0700816 struct key *,
David Howells08e0e7c2007-04-26 15:55:03 -0700817 const char *, size_t);
David Howellsf044c882017-11-02 15:27:45 +0000818extern void afs_put_vlocation(struct afs_net *, struct afs_vlocation *);
819extern void afs_vlocation_updater(struct work_struct *);
820extern void afs_vlocation_reaper(struct work_struct *);
821extern void __net_exit afs_vlocation_purge(struct afs_net *);
David Howells08e0e7c2007-04-26 15:55:03 -0700822
823/*
824 * vnode.c
825 */
David Howells08e0e7c2007-04-26 15:55:03 -0700826static inline struct afs_vnode *AFS_FS_I(struct inode *inode)
827{
828 return container_of(inode, struct afs_vnode, vfs_inode);
829}
830
831static inline struct inode *AFS_VNODE_TO_I(struct afs_vnode *vnode)
832{
833 return &vnode->vfs_inode;
834}
835
David Howells260a9802007-04-26 15:59:35 -0700836extern void afs_vnode_finalise_status_update(struct afs_vnode *,
837 struct afs_server *);
David Howellsbe080a62017-11-02 15:27:49 +0000838extern int afs_vnode_fetch_status(struct afs_vnode *, struct key *, bool);
David Howells00d3b7a2007-04-26 15:57:07 -0700839extern int afs_vnode_fetch_data(struct afs_vnode *, struct key *,
David Howells196ee9c2017-01-05 10:38:34 +0000840 struct afs_read *);
David Howells260a9802007-04-26 15:59:35 -0700841extern int afs_vnode_create(struct afs_vnode *, struct key *, const char *,
842 umode_t, struct afs_fid *, struct afs_file_status *,
843 struct afs_callback *, struct afs_server **);
844extern int afs_vnode_remove(struct afs_vnode *, struct key *, const char *,
845 bool);
846extern int afs_vnode_link(struct afs_vnode *, struct afs_vnode *, struct key *,
847 const char *);
848extern int afs_vnode_symlink(struct afs_vnode *, struct key *, const char *,
849 const char *, struct afs_fid *,
850 struct afs_file_status *, struct afs_server **);
851extern int afs_vnode_rename(struct afs_vnode *, struct afs_vnode *,
852 struct key *, const char *, const char *);
David Howells31143d52007-05-09 02:33:46 -0700853extern int afs_vnode_store_data(struct afs_writeback *, pgoff_t, pgoff_t,
854 unsigned, unsigned);
855extern int afs_vnode_setattr(struct afs_vnode *, struct key *, struct iattr *);
David Howells45222b92007-05-10 22:22:20 -0700856extern int afs_vnode_get_volume_status(struct afs_vnode *, struct key *,
857 struct afs_volume_status *);
David Howellse8d6c552007-07-15 23:40:12 -0700858extern int afs_vnode_set_lock(struct afs_vnode *, struct key *,
859 afs_lock_type_t);
860extern int afs_vnode_extend_lock(struct afs_vnode *, struct key *);
861extern int afs_vnode_release_lock(struct afs_vnode *, struct key *);
David Howells08e0e7c2007-04-26 15:55:03 -0700862
863/*
864 * volume.c
865 */
David Howells49566f62017-11-02 15:27:46 +0000866static inline struct afs_volume *afs_get_volume(struct afs_volume *volume)
867{
868 if (volume)
869 atomic_inc(&volume->usage);
870 return volume;
871}
David Howells08e0e7c2007-04-26 15:55:03 -0700872
David Howells9ed900b2017-11-02 15:27:46 +0000873extern void afs_put_volume(struct afs_cell *, struct afs_volume *);
David Howells00d3b7a2007-04-26 15:57:07 -0700874extern struct afs_volume *afs_volume_lookup(struct afs_mount_params *);
David Howells8b2a4642017-11-02 15:27:50 +0000875extern void afs_init_fs_cursor(struct afs_fs_cursor *, struct afs_vnode *);
876extern int afs_set_fs_cursor(struct afs_fs_cursor *, struct afs_vnode *);
877extern bool afs_volume_pick_fileserver(struct afs_fs_cursor *, struct afs_vnode *);
878extern bool afs_iterate_fs_cursor(struct afs_fs_cursor *, struct afs_vnode *);
879extern int afs_end_fs_cursor(struct afs_fs_cursor *, struct afs_net *);
David Howells08e0e7c2007-04-26 15:55:03 -0700880
David Howells31143d52007-05-09 02:33:46 -0700881/*
882 * write.c
883 */
884extern int afs_set_page_dirty(struct page *);
885extern void afs_put_writeback(struct afs_writeback *);
Nick Piggin15b46502008-10-15 22:04:32 -0700886extern int afs_write_begin(struct file *file, struct address_space *mapping,
887 loff_t pos, unsigned len, unsigned flags,
888 struct page **pagep, void **fsdata);
889extern int afs_write_end(struct file *file, struct address_space *mapping,
890 loff_t pos, unsigned len, unsigned copied,
891 struct page *page, void *fsdata);
David Howells31143d52007-05-09 02:33:46 -0700892extern int afs_writepage(struct page *, struct writeback_control *);
893extern int afs_writepages(struct address_space *, struct writeback_control *);
David Howells31143d52007-05-09 02:33:46 -0700894extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *);
Al Viro50b55512014-04-03 14:13:46 -0400895extern ssize_t afs_file_write(struct kiocb *, struct iov_iter *);
David Howells31143d52007-05-09 02:33:46 -0700896extern int afs_writeback_all(struct afs_vnode *);
David Howells58fed942017-03-16 16:27:45 +0000897extern int afs_flush(struct file *, fl_owner_t);
Josef Bacik02c24a82011-07-16 20:44:56 -0400898extern int afs_fsync(struct file *, loff_t, loff_t, int);
David Howells31143d52007-05-09 02:33:46 -0700899
David Howellsd3e3b7ea2017-07-06 15:50:27 +0100900/*
901 * xattr.c
902 */
903extern const struct xattr_handler *afs_xattr_handlers[];
904extern ssize_t afs_listxattr(struct dentry *, char *, size_t);
David Howells31143d52007-05-09 02:33:46 -0700905
David Howells08e0e7c2007-04-26 15:55:03 -0700906/*****************************************************************************/
907/*
908 * debug tracing
909 */
David Howells8e8d7f12017-01-05 10:38:34 +0000910#include <trace/events/afs.h>
911
David Howells08e0e7c2007-04-26 15:55:03 -0700912extern unsigned afs_debug;
913
914#define dbgprintk(FMT,...) \
Sven Schnellead16df82008-04-03 10:44:01 +0100915 printk("[%-6.6s] "FMT"\n", current->comm ,##__VA_ARGS__)
David Howells08e0e7c2007-04-26 15:55:03 -0700916
Harvey Harrison530b6412008-04-30 00:55:09 -0700917#define kenter(FMT,...) dbgprintk("==> %s("FMT")",__func__ ,##__VA_ARGS__)
918#define kleave(FMT,...) dbgprintk("<== %s()"FMT"",__func__ ,##__VA_ARGS__)
David Howells08e0e7c2007-04-26 15:55:03 -0700919#define kdebug(FMT,...) dbgprintk(" "FMT ,##__VA_ARGS__)
920
921
922#if defined(__KDEBUG)
923#define _enter(FMT,...) kenter(FMT,##__VA_ARGS__)
924#define _leave(FMT,...) kleave(FMT,##__VA_ARGS__)
925#define _debug(FMT,...) kdebug(FMT,##__VA_ARGS__)
926
927#elif defined(CONFIG_AFS_DEBUG)
928#define AFS_DEBUG_KENTER 0x01
929#define AFS_DEBUG_KLEAVE 0x02
930#define AFS_DEBUG_KDEBUG 0x04
931
932#define _enter(FMT,...) \
933do { \
934 if (unlikely(afs_debug & AFS_DEBUG_KENTER)) \
935 kenter(FMT,##__VA_ARGS__); \
936} while (0)
937
938#define _leave(FMT,...) \
939do { \
940 if (unlikely(afs_debug & AFS_DEBUG_KLEAVE)) \
941 kleave(FMT,##__VA_ARGS__); \
942} while (0)
943
944#define _debug(FMT,...) \
945do { \
946 if (unlikely(afs_debug & AFS_DEBUG_KDEBUG)) \
947 kdebug(FMT,##__VA_ARGS__); \
948} while (0)
949
950#else
David Howells12fdff32010-08-12 16:54:57 +0100951#define _enter(FMT,...) no_printk("==> %s("FMT")",__func__ ,##__VA_ARGS__)
952#define _leave(FMT,...) no_printk("<== %s()"FMT"",__func__ ,##__VA_ARGS__)
953#define _debug(FMT,...) no_printk(" "FMT ,##__VA_ARGS__)
David Howells08e0e7c2007-04-26 15:55:03 -0700954#endif
955
956/*
957 * debug assertion checking
958 */
959#if 1 // defined(__KDEBUGALL)
960
961#define ASSERT(X) \
962do { \
963 if (unlikely(!(X))) { \
964 printk(KERN_ERR "\n"); \
965 printk(KERN_ERR "AFS: Assertion failed\n"); \
966 BUG(); \
967 } \
968} while(0)
969
970#define ASSERTCMP(X, OP, Y) \
971do { \
972 if (unlikely(!((X) OP (Y)))) { \
973 printk(KERN_ERR "\n"); \
974 printk(KERN_ERR "AFS: Assertion failed\n"); \
975 printk(KERN_ERR "%lu " #OP " %lu is false\n", \
976 (unsigned long)(X), (unsigned long)(Y)); \
977 printk(KERN_ERR "0x%lx " #OP " 0x%lx is false\n", \
978 (unsigned long)(X), (unsigned long)(Y)); \
979 BUG(); \
980 } \
981} while(0)
982
David Howells416351f2007-05-09 02:33:45 -0700983#define ASSERTRANGE(L, OP1, N, OP2, H) \
984do { \
985 if (unlikely(!((L) OP1 (N)) || !((N) OP2 (H)))) { \
986 printk(KERN_ERR "\n"); \
987 printk(KERN_ERR "AFS: Assertion failed\n"); \
988 printk(KERN_ERR "%lu "#OP1" %lu "#OP2" %lu is false\n", \
989 (unsigned long)(L), (unsigned long)(N), \
990 (unsigned long)(H)); \
991 printk(KERN_ERR "0x%lx "#OP1" 0x%lx "#OP2" 0x%lx is false\n", \
992 (unsigned long)(L), (unsigned long)(N), \
993 (unsigned long)(H)); \
994 BUG(); \
995 } \
996} while(0)
997
David Howells08e0e7c2007-04-26 15:55:03 -0700998#define ASSERTIF(C, X) \
999do { \
1000 if (unlikely((C) && !(X))) { \
1001 printk(KERN_ERR "\n"); \
1002 printk(KERN_ERR "AFS: Assertion failed\n"); \
1003 BUG(); \
1004 } \
1005} while(0)
1006
1007#define ASSERTIFCMP(C, X, OP, Y) \
1008do { \
1009 if (unlikely((C) && !((X) OP (Y)))) { \
1010 printk(KERN_ERR "\n"); \
1011 printk(KERN_ERR "AFS: Assertion failed\n"); \
1012 printk(KERN_ERR "%lu " #OP " %lu is false\n", \
1013 (unsigned long)(X), (unsigned long)(Y)); \
1014 printk(KERN_ERR "0x%lx " #OP " 0x%lx is false\n", \
1015 (unsigned long)(X), (unsigned long)(Y)); \
1016 BUG(); \
1017 } \
1018} while(0)
1019
1020#else
1021
1022#define ASSERT(X) \
1023do { \
1024} while(0)
1025
1026#define ASSERTCMP(X, OP, Y) \
1027do { \
1028} while(0)
1029
David Howells416351f2007-05-09 02:33:45 -07001030#define ASSERTRANGE(L, OP1, N, OP2, H) \
1031do { \
1032} while(0)
1033
David Howells08e0e7c2007-04-26 15:55:03 -07001034#define ASSERTIF(C, X) \
1035do { \
1036} while(0)
1037
1038#define ASSERTIFCMP(C, X, OP, Y) \
1039do { \
1040} while(0)
1041
1042#endif /* __KDEBUGALL */