blob: f8086ec95e24161eb9b9900745275e1cc4c1cfc6 [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
David Howells00d3b7a2007-04-26 15:57:07 -070035struct afs_mount_params {
36 bool rwpath; /* T if the parent should be considered R/W */
37 bool force; /* T to force cell type */
wangleibec5eb62010-08-11 09:38:04 +010038 bool autocell; /* T if set auto mount operation */
David Howells4d673da2018-02-06 06:26:30 +000039 bool dyn_root; /* T if dynamic root */
David Howells00d3b7a2007-04-26 15:57:07 -070040 afs_voltype_t type; /* type of volume requested */
41 int volnamesz; /* size of volume name */
42 const char *volname; /* name of volume to mount */
David Howellsf044c882017-11-02 15:27:45 +000043 struct afs_net *net; /* Network namespace in effect */
David Howells00d3b7a2007-04-26 15:57:07 -070044 struct afs_cell *cell; /* cell in which to find volume */
45 struct afs_volume *volume; /* volume record */
46 struct key *key; /* key to use for secure mounting */
47};
48
David Howellsc435ee32017-11-02 15:27:49 +000049struct afs_iget_data {
50 struct afs_fid fid;
51 struct afs_volume *volume; /* volume on which resides */
52};
53
David Howells8e8d7f12017-01-05 10:38:34 +000054enum afs_call_state {
David Howells98bf40c2017-11-02 15:27:53 +000055 AFS_CALL_CL_REQUESTING, /* Client: Request is being sent */
56 AFS_CALL_CL_AWAIT_REPLY, /* Client: Awaiting reply */
57 AFS_CALL_CL_PROC_REPLY, /* Client: rxrpc call complete; processing reply */
58 AFS_CALL_SV_AWAIT_OP_ID, /* Server: Awaiting op ID */
59 AFS_CALL_SV_AWAIT_REQUEST, /* Server: Awaiting request data */
60 AFS_CALL_SV_REPLYING, /* Server: Replying */
61 AFS_CALL_SV_AWAIT_ACK, /* Server: Awaiting final ACK */
62 AFS_CALL_COMPLETE, /* Completed or failed */
David Howells8e8d7f12017-01-05 10:38:34 +000063};
David Howellsf044c882017-11-02 15:27:45 +000064
David Howells08e0e7c2007-04-26 15:55:03 -070065/*
David Howells8b2a4642017-11-02 15:27:50 +000066 * List of server addresses.
67 */
68struct afs_addr_list {
69 struct rcu_head rcu; /* Must be first */
70 refcount_t usage;
David Howellsd2ddc772017-11-02 15:27:50 +000071 u32 version; /* Version */
David Howells8b2a4642017-11-02 15:27:50 +000072 unsigned short nr_addrs;
73 unsigned short index; /* Address currently in use */
David Howellsd2ddc772017-11-02 15:27:50 +000074 unsigned short nr_ipv4; /* Number of IPv4 addresses */
David Howellsbf99a532017-11-02 15:27:51 +000075 unsigned long probed; /* Mask of servers that have been probed */
76 unsigned long yfs; /* Mask of servers that are YFS */
David Howells8b2a4642017-11-02 15:27:50 +000077 struct sockaddr_rxrpc addrs[];
78};
79
80/*
David Howells08e0e7c2007-04-26 15:55:03 -070081 * a record of an in-progress RxRPC call
82 */
83struct afs_call {
84 const struct afs_call_type *type; /* type of call */
David Howells08e0e7c2007-04-26 15:55:03 -070085 wait_queue_head_t waitq; /* processes awaiting completion */
David Howells341f7412017-01-05 10:38:36 +000086 struct work_struct async_work; /* async I/O processor */
David Howells08e0e7c2007-04-26 15:55:03 -070087 struct work_struct work; /* actual work processor */
David Howells08e0e7c2007-04-26 15:55:03 -070088 struct rxrpc_call *rxcall; /* RxRPC call handle */
89 struct key *key; /* security for this call */
David Howellsf044c882017-11-02 15:27:45 +000090 struct afs_net *net; /* The network namespace */
David Howellsd0676a12017-11-02 15:27:49 +000091 struct afs_server *cm_server; /* Server affected by incoming CM call */
David Howellsd2ddc772017-11-02 15:27:50 +000092 struct afs_cb_interest *cbi; /* Callback interest for server used */
David Howells08e0e7c2007-04-26 15:55:03 -070093 void *request; /* request data (first part) */
David Howells4343d002017-11-02 15:27:52 +000094 struct address_space *mapping; /* Pages being written from */
David Howells08e0e7c2007-04-26 15:55:03 -070095 void *buffer; /* reply receive buffer */
David Howells97e30432017-11-02 15:27:48 +000096 void *reply[4]; /* Where to put the reply */
David Howells31143d52007-05-09 02:33:46 -070097 pgoff_t first; /* first page in mapping to deal with */
98 pgoff_t last; /* last page in mapping to deal with */
David Howellsd0016482016-08-30 20:42:14 +010099 size_t offset; /* offset into received data store */
David Howells341f7412017-01-05 10:38:36 +0000100 atomic_t usage;
David Howells8e8d7f12017-01-05 10:38:34 +0000101 enum afs_call_state state;
David Howells98bf40c2017-11-02 15:27:53 +0000102 spinlock_t state_lock;
David Howells08e0e7c2007-04-26 15:55:03 -0700103 int error; /* error code */
David Howellsd0016482016-08-30 20:42:14 +0100104 u32 abort_code; /* Remote abort ID or 0 */
David Howells08e0e7c2007-04-26 15:55:03 -0700105 unsigned request_size; /* size of request data */
106 unsigned reply_max; /* maximum size of reply */
David Howells31143d52007-05-09 02:33:46 -0700107 unsigned first_offset; /* offset into mapping[first] */
David Howellsc435ee32017-11-02 15:27:49 +0000108 unsigned int cb_break; /* cb_break + cb_s_break before the call */
Marc Dionnebcd89272017-03-16 16:27:44 +0000109 union {
110 unsigned last_to; /* amount of mapping[last] */
111 unsigned count2; /* count used in unmarshalling */
112 };
David Howells08e0e7c2007-04-26 15:55:03 -0700113 unsigned char unmarshall; /* unmarshalling phase */
114 bool incoming; /* T if incoming call */
David Howells31143d52007-05-09 02:33:46 -0700115 bool send_pages; /* T if data from mapping should be sent */
David Howellsd0016482016-08-30 20:42:14 +0100116 bool need_attention; /* T if RxRPC poked us */
David Howells56ff9c82017-01-05 10:38:36 +0000117 bool async; /* T if asynchronous */
David Howells33cd7f22017-11-02 15:27:48 +0000118 bool ret_reply0; /* T if should return reply[0] on success */
David Howellsa68f4a22017-10-18 11:36:39 +0100119 bool upgrade; /* T to request service upgrade */
David Howellsbf99a532017-11-02 15:27:51 +0000120 u16 service_id; /* Actual service ID (after upgrade) */
David Howellsa25e21f2018-03-27 23:03:00 +0100121 unsigned int debug_id; /* Trace ID */
David Howells50a2c952016-10-13 08:27:10 +0100122 u32 operation_ID; /* operation ID for an incoming call */
David Howells08e0e7c2007-04-26 15:55:03 -0700123 u32 count; /* count for use in unmarshalling */
124 __be32 tmp; /* place to extract temporary data */
David Howells0c3a5ac2018-04-06 14:17:24 +0100125 afs_dataversion_t expected_version; /* Updated version expected from store */
126 afs_dataversion_t expected_version_2; /* 2nd updated version expected from store */
David Howells08e0e7c2007-04-26 15:55:03 -0700127};
128
129struct afs_call_type {
David Howells00d3b7a2007-04-26 15:57:07 -0700130 const char *name;
David Howells025db802017-11-02 15:27:51 +0000131 unsigned int op; /* Really enum afs_fs_operation */
David Howells00d3b7a2007-04-26 15:57:07 -0700132
David Howells08e0e7c2007-04-26 15:55:03 -0700133 /* deliver request or reply data to an call
134 * - returning an error will cause the call to be aborted
135 */
David Howellsd0016482016-08-30 20:42:14 +0100136 int (*deliver)(struct afs_call *call);
David Howells08e0e7c2007-04-26 15:55:03 -0700137
David Howells08e0e7c2007-04-26 15:55:03 -0700138 /* clean up a call */
139 void (*destructor)(struct afs_call *call);
David Howells341f7412017-01-05 10:38:36 +0000140
141 /* Work function */
142 void (*work)(struct work_struct *work);
David Howells08e0e7c2007-04-26 15:55:03 -0700143};
144
145/*
David Howells4343d002017-11-02 15:27:52 +0000146 * Key available for writeback on a file.
147 */
148struct afs_wb_key {
149 refcount_t usage;
150 struct key *key;
151 struct list_head vnode_link; /* Link in vnode->wb_keys */
152};
153
154/*
David Howells215804a2017-11-02 15:27:52 +0000155 * AFS open file information record. Pointed to by file->private_data.
156 */
157struct afs_file {
158 struct key *key; /* The key this file was opened with */
David Howells4343d002017-11-02 15:27:52 +0000159 struct afs_wb_key *wb; /* Writeback key record for this file */
David Howells215804a2017-11-02 15:27:52 +0000160};
161
162static inline struct key *afs_file_key(struct file *file)
163{
164 struct afs_file *af = file->private_data;
165
166 return af->key;
167}
168
169/*
David Howells196ee9c2017-01-05 10:38:34 +0000170 * Record of an outstanding read operation on a vnode.
171 */
172struct afs_read {
173 loff_t pos; /* Where to start reading */
David Howellse8e581a2017-03-16 16:27:44 +0000174 loff_t len; /* How much we're asking for */
David Howells196ee9c2017-01-05 10:38:34 +0000175 loff_t actual_len; /* How much we're actually getting */
David Howells6a0e3992017-03-16 16:27:46 +0000176 loff_t remain; /* Amount remaining */
David Howellsf3ddee82018-04-06 14:17:25 +0100177 loff_t file_size; /* File size returned by server */
178 afs_dataversion_t data_version; /* Version number returned by server */
179 refcount_t usage;
David Howells196ee9c2017-01-05 10:38:34 +0000180 unsigned int index; /* Which page we're reading into */
David Howells196ee9c2017-01-05 10:38:34 +0000181 unsigned int nr_pages;
182 void (*page_done)(struct afs_call *, struct afs_read *);
David Howellsf3ddee82018-04-06 14:17:25 +0100183 struct page **pages;
184 struct page *array[];
David Howells196ee9c2017-01-05 10:38:34 +0000185};
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 */
David Howells4d673da2018-02-06 06:26:30 +0000195 bool dyn_root; /* True if dynamic root */
David Howells08e0e7c2007-04-26 15:55:03 -0700196};
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 Howells6f8880d2018-04-09 21:12:31 +0100206 * Set of substitutes for @sys.
207 */
208struct afs_sysnames {
209#define AFS_NR_SYSNAME 16
210 char *subs[AFS_NR_SYSNAME];
211 refcount_t usage;
212 unsigned short nr;
213 short error;
214 char blank[1];
215};
216
217/*
David Howellsf044c882017-11-02 15:27:45 +0000218 * AFS network namespace record.
219 */
220struct afs_net {
221 struct afs_uuid uuid;
222 bool live; /* F if this namespace is being removed */
223
224 /* AF_RXRPC I/O stuff */
225 struct socket *socket;
226 struct afs_call *spare_incoming_call;
227 struct work_struct charge_preallocation_work;
228 struct mutex socket_mutex;
229 atomic_t nr_outstanding_calls;
230 atomic_t nr_superblocks;
231
232 /* Cell database */
David Howells989782d2017-11-02 15:27:50 +0000233 struct rb_root cells;
David Howellsf044c882017-11-02 15:27:45 +0000234 struct afs_cell *ws_cell;
David Howells989782d2017-11-02 15:27:50 +0000235 struct work_struct cells_manager;
236 struct timer_list cells_timer;
237 atomic_t cells_outstanding;
238 seqlock_t cells_lock;
David Howellsf044c882017-11-02 15:27:45 +0000239
David Howells989782d2017-11-02 15:27:50 +0000240 spinlock_t proc_cells_lock;
David Howellsf044c882017-11-02 15:27:45 +0000241 struct list_head proc_cells;
242
David Howellsd2ddc772017-11-02 15:27:50 +0000243 /* Known servers. Theoretically each fileserver can only be in one
244 * cell, but in practice, people create aliases and subsets and there's
245 * no easy way to distinguish them.
246 */
247 seqlock_t fs_lock; /* For fs_servers */
248 struct rb_root fs_servers; /* afs_server (by server UUID or address) */
249 struct list_head fs_updates; /* afs_server (by update_at) */
250 struct hlist_head fs_proc; /* procfs servers list */
251
252 struct hlist_head fs_addresses4; /* afs_server (by lowest IPv4 addr) */
253 struct hlist_head fs_addresses6; /* afs_server (by lowest IPv6 addr) */
254 seqlock_t fs_addr_lock; /* For fs_addresses[46] */
255
256 struct work_struct fs_manager;
257 struct timer_list fs_timer;
258 atomic_t servers_outstanding;
David Howellsf044c882017-11-02 15:27:45 +0000259
260 /* File locking renewal management */
261 struct mutex lock_manager_mutex;
262
David Howellsf044c882017-11-02 15:27:45 +0000263 /* Misc */
David Howellsd55b4da2018-04-06 14:17:24 +0100264 struct proc_dir_entry *proc_afs; /* /proc/net/afs directory */
David Howells6f8880d2018-04-09 21:12:31 +0100265 struct afs_sysnames *sysnames;
266 rwlock_t sysnames_lock;
David Howellsd55b4da2018-04-06 14:17:24 +0100267
268 /* Statistics counters */
269 atomic_t n_lookup; /* Number of lookups done */
270 atomic_t n_reval; /* Number of dentries needing revalidation */
271 atomic_t n_inval; /* Number of invalidations by the server */
David Howellsf3ddee82018-04-06 14:17:25 +0100272 atomic_t n_relpg; /* Number of invalidations by releasepage */
David Howellsd55b4da2018-04-06 14:17:24 +0100273 atomic_t n_read_dir; /* Number of directory pages read */
David Howells63a46812018-04-06 14:17:25 +0100274 atomic_t n_dir_cr; /* Number of directory entry creation edits */
275 atomic_t n_dir_rm; /* Number of directory entry removal edits */
David Howells76a5cb62018-04-06 14:17:26 +0100276 atomic_t n_stores; /* Number of store ops */
277 atomic_long_t n_store_bytes; /* Number of bytes stored */
278 atomic_long_t n_fetch_bytes; /* Number of bytes fetched */
279 atomic_t n_fetches; /* Number of data fetch ops */
David Howellsf044c882017-11-02 15:27:45 +0000280};
281
David Howells6f8880d2018-04-09 21:12:31 +0100282extern const char afs_init_sysname[];
David Howellsf044c882017-11-02 15:27:45 +0000283extern struct afs_net __afs_net;// Dummy AFS network namespace; TODO: replace with real netns
284
David Howells989782d2017-11-02 15:27:50 +0000285enum afs_cell_state {
286 AFS_CELL_UNSET,
287 AFS_CELL_ACTIVATING,
288 AFS_CELL_ACTIVE,
289 AFS_CELL_DEACTIVATING,
290 AFS_CELL_INACTIVE,
291 AFS_CELL_FAILED,
292};
293
David Howellsf044c882017-11-02 15:27:45 +0000294/*
David Howellsd2ddc772017-11-02 15:27:50 +0000295 * AFS cell record.
296 *
297 * This is a tricky concept to get right as it is possible to create aliases
298 * simply by pointing AFSDB/SRV records for two names at the same set of VL
299 * servers; it is also possible to do things like setting up two sets of VL
300 * servers, one of which provides a superset of the volumes provided by the
301 * other (for internal/external division, for example).
302 *
303 * Cells only exist in the sense that (a) a cell's name maps to a set of VL
304 * servers and (b) a cell's name is used by the client to select the key to use
305 * for authentication and encryption. The cell name is not typically used in
306 * the protocol.
307 *
308 * There is no easy way to determine if two cells are aliases or one is a
309 * subset of another.
David Howells08e0e7c2007-04-26 15:55:03 -0700310 */
311struct afs_cell {
David Howells989782d2017-11-02 15:27:50 +0000312 union {
313 struct rcu_head rcu;
314 struct rb_node net_node; /* Node in net->cells */
315 };
316 struct afs_net *net;
David Howells00d3b7a2007-04-26 15:57:07 -0700317 struct key *anonymous_key; /* anonymous user key for this cell */
David Howells989782d2017-11-02 15:27:50 +0000318 struct work_struct manager; /* Manager for init/deinit/dns */
David Howells08e0e7c2007-04-26 15:55:03 -0700319 struct list_head proc_link; /* /proc cell list link */
David Howells9b3f26c2009-04-03 16:42:41 +0100320#ifdef CONFIG_AFS_FSCACHE
321 struct fscache_cookie *cache; /* caching cookie */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322#endif
David Howells989782d2017-11-02 15:27:50 +0000323 time64_t dns_expiry; /* Time AFSDB/SRV record expires */
324 time64_t last_inactive; /* Time of last drop of usage count */
325 atomic_t usage;
326 unsigned long flags;
327#define AFS_CELL_FL_NOT_READY 0 /* The cell record is not ready for use */
328#define AFS_CELL_FL_NO_GC 1 /* The cell was added manually, don't auto-gc */
329#define AFS_CELL_FL_NOT_FOUND 2 /* Permanent DNS error */
330#define AFS_CELL_FL_DNS_FAIL 3 /* Failed to access DNS */
David Howells8b2a4642017-11-02 15:27:50 +0000331#define AFS_CELL_FL_NO_LOOKUP_YET 4 /* Not completed first DNS lookup yet */
David Howells989782d2017-11-02 15:27:50 +0000332 enum afs_cell_state state;
333 short error;
334
David Howellsd2ddc772017-11-02 15:27:50 +0000335 /* Active fileserver interaction state. */
336 struct list_head proc_volumes; /* procfs volume list */
337 rwlock_t proc_lock;
David Howells989782d2017-11-02 15:27:50 +0000338
David Howellsd2ddc772017-11-02 15:27:50 +0000339 /* VL server list. */
David Howells8b2a4642017-11-02 15:27:50 +0000340 rwlock_t vl_addrs_lock; /* Lock on vl_addrs */
341 struct afs_addr_list __rcu *vl_addrs; /* List of VL servers */
David Howells989782d2017-11-02 15:27:50 +0000342 u8 name_len; /* Length of name */
343 char name[64 + 1]; /* Cell name, case-flattened and NUL-padded */
David Howells08e0e7c2007-04-26 15:55:03 -0700344};
345
346/*
David Howellsd2ddc772017-11-02 15:27:50 +0000347 * Cached VLDB entry.
348 *
349 * This is pointed to by cell->vldb_entries, indexed by name.
David Howells08e0e7c2007-04-26 15:55:03 -0700350 */
David Howellsd2ddc772017-11-02 15:27:50 +0000351struct afs_vldb_entry {
352 afs_volid_t vid[3]; /* Volume IDs for R/W, R/O and Bak volumes */
David Howells00d3b7a2007-04-26 15:57:07 -0700353
David Howellsd2ddc772017-11-02 15:27:50 +0000354 unsigned long flags;
355#define AFS_VLDB_HAS_RW 0 /* - R/W volume exists */
356#define AFS_VLDB_HAS_RO 1 /* - R/O volume exists */
357#define AFS_VLDB_HAS_BAK 2 /* - Backup volume exists */
358#define AFS_VLDB_QUERY_VALID 3 /* - Record is valid */
359#define AFS_VLDB_QUERY_ERROR 4 /* - VL server returned error */
360
361 uuid_t fs_server[AFS_NMAXNSERVERS];
362 u8 fs_mask[AFS_NMAXNSERVERS];
David Howells08e0e7c2007-04-26 15:55:03 -0700363#define AFS_VOL_VTM_RW 0x01 /* R/W version of the volume is available (on this server) */
364#define AFS_VOL_VTM_RO 0x02 /* R/O version of the volume is available (on this server) */
365#define AFS_VOL_VTM_BAK 0x04 /* backup version of the volume is available (on this server) */
David Howellsd2ddc772017-11-02 15:27:50 +0000366 short error;
367 u8 nr_servers; /* Number of server records */
368 u8 name_len;
369 u8 name[AFS_MAXVOLNAME + 1]; /* NUL-padded volume name */
David Howells08e0e7c2007-04-26 15:55:03 -0700370};
371
372/*
David Howellsd2ddc772017-11-02 15:27:50 +0000373 * Record of fileserver with which we're actively communicating.
David Howells08e0e7c2007-04-26 15:55:03 -0700374 */
375struct afs_server {
David Howellsd2ddc772017-11-02 15:27:50 +0000376 struct rcu_head rcu;
377 union {
378 uuid_t uuid; /* Server ID */
379 struct afs_uuid _uuid;
380 };
David Howellsc435ee32017-11-02 15:27:49 +0000381
David Howellsd2ddc772017-11-02 15:27:50 +0000382 struct afs_addr_list __rcu *addresses;
383 struct rb_node uuid_rb; /* Link in net->servers */
384 struct hlist_node addr4_link; /* Link in net->fs_addresses4 */
385 struct hlist_node addr6_link; /* Link in net->fs_addresses6 */
386 struct hlist_node proc_link; /* Link in net->fs_proc */
387 struct afs_server *gc_next; /* Next server in manager's list */
388 time64_t put_time; /* Time at which last put */
389 time64_t update_at; /* Time at which to next update the record */
David Howellsc435ee32017-11-02 15:27:49 +0000390 unsigned long flags;
David Howellsd2ddc772017-11-02 15:27:50 +0000391#define AFS_SERVER_FL_NEW 0 /* New server, don't inc cb_s_break */
392#define AFS_SERVER_FL_NOT_READY 1 /* The record is not ready for use */
393#define AFS_SERVER_FL_NOT_FOUND 2 /* VL server says no such server */
394#define AFS_SERVER_FL_VL_FAIL 3 /* Failed to access VL server */
395#define AFS_SERVER_FL_UPDATING 4
396#define AFS_SERVER_FL_PROBED 5 /* The fileserver has been probed */
397#define AFS_SERVER_FL_PROBING 6 /* Fileserver is being probed */
David Howells5cf9dd52018-04-09 21:12:31 +0100398#define AFS_SERVER_FL_NO_IBULK 7 /* Fileserver doesn't support FS.InlineBulkStatus */
David Howellsd2ddc772017-11-02 15:27:50 +0000399 atomic_t usage;
400 u32 addr_version; /* Address list version */
David Howells08e0e7c2007-04-26 15:55:03 -0700401
402 /* file service access */
David Howellsd2ddc772017-11-02 15:27:50 +0000403 rwlock_t fs_lock; /* access lock */
David Howells08e0e7c2007-04-26 15:55:03 -0700404
405 /* callback promise management */
David Howellsc435ee32017-11-02 15:27:49 +0000406 struct list_head cb_interests; /* List of superblocks using this server */
407 unsigned cb_s_break; /* Break-everything counter. */
408 rwlock_t cb_break_lock; /* Volume finding lock */
409};
410
411/*
412 * Interest by a superblock on a server.
413 */
414struct afs_cb_interest {
415 struct list_head cb_link; /* Link in server->cb_interests */
416 struct afs_server *server; /* Server on which this interest resides */
417 struct super_block *sb; /* Superblock on which inodes reside */
418 afs_volid_t vid; /* Volume ID to match */
419 refcount_t usage;
David Howells08e0e7c2007-04-26 15:55:03 -0700420};
421
422/*
David Howellsd2ddc772017-11-02 15:27:50 +0000423 * Replaceable server list.
David Howells08e0e7c2007-04-26 15:55:03 -0700424 */
David Howellsd2ddc772017-11-02 15:27:50 +0000425struct afs_server_entry {
426 struct afs_server *server;
427 struct afs_cb_interest *cb_interest;
428};
429
430struct afs_server_list {
431 refcount_t usage;
432 unsigned short nr_servers;
433 unsigned short index; /* Server currently in use */
434 unsigned short vnovol_mask; /* Servers to be skipped due to VNOVOL */
435 unsigned int seq; /* Set to ->servers_seq when installed */
436 struct afs_server_entry servers[];
David Howells08e0e7c2007-04-26 15:55:03 -0700437};
438
439/*
David Howellsd2ddc772017-11-02 15:27:50 +0000440 * Live AFS volume management.
David Howells08e0e7c2007-04-26 15:55:03 -0700441 */
David Howellsd2ddc772017-11-02 15:27:50 +0000442struct afs_volume {
443 afs_volid_t vid; /* volume ID */
444 atomic_t usage;
445 time64_t update_at; /* Time at which to next update */
446 struct afs_cell *cell; /* Cell to which belongs (pins ref) */
447 struct list_head proc_link; /* Link in cell->vl_proc */
448 unsigned long flags;
449#define AFS_VOLUME_NEEDS_UPDATE 0 /* - T if an update needs performing */
450#define AFS_VOLUME_UPDATING 1 /* - T if an update is in progress */
451#define AFS_VOLUME_WAIT 2 /* - T if users must wait for update */
452#define AFS_VOLUME_DELETED 3 /* - T if volume appears deleted */
453#define AFS_VOLUME_OFFLINE 4 /* - T if volume offline notice given */
454#define AFS_VOLUME_BUSY 5 /* - T if volume busy notice given */
455#ifdef CONFIG_AFS_FSCACHE
456 struct fscache_cookie *cache; /* caching cookie */
457#endif
458 struct afs_server_list *servers; /* List of servers on which volume resides */
459 rwlock_t servers_lock; /* Lock for ->servers */
460 unsigned int servers_seq; /* Incremented each time ->servers changes */
461
462 afs_voltype_t type; /* type of volume */
463 short error;
464 char type_force; /* force volume type (suppress R/O -> R/W) */
465 u8 name_len;
466 u8 name[AFS_MAXVOLNAME + 1]; /* NUL-padded volume name */
David Howells08e0e7c2007-04-26 15:55:03 -0700467};
468
David Howells0fafdc92017-11-13 16:59:50 +0000469enum afs_lock_state {
470 AFS_VNODE_LOCK_NONE, /* The vnode has no lock on the server */
471 AFS_VNODE_LOCK_WAITING_FOR_CB, /* We're waiting for the server to break the callback */
472 AFS_VNODE_LOCK_SETTING, /* We're asking the server for a lock */
473 AFS_VNODE_LOCK_GRANTED, /* We have a lock on the server */
474 AFS_VNODE_LOCK_EXTENDING, /* We're extending a lock on the server */
475 AFS_VNODE_LOCK_NEED_UNLOCK, /* We need to unlock on the server */
476 AFS_VNODE_LOCK_UNLOCKING, /* We're telling the server to unlock */
477};
478
David Howells08e0e7c2007-04-26 15:55:03 -0700479/*
David Howellsf8de4832017-12-01 11:40:43 +0000480 * AFS inode private data.
481 *
482 * Note that afs_alloc_inode() *must* reset anything that could incorrectly
483 * leak from one inode to another.
David Howells08e0e7c2007-04-26 15:55:03 -0700484 */
485struct afs_vnode {
486 struct inode vfs_inode; /* the VFS's inode record */
487
488 struct afs_volume *volume; /* volume on which vnode resides */
David Howells08e0e7c2007-04-26 15:55:03 -0700489 struct afs_fid fid; /* the file identifier for this inode */
490 struct afs_file_status status; /* AFS status info for this file */
David Howellsa4ff7402018-04-06 14:17:24 +0100491 afs_dataversion_t invalid_before; /* Child dentries are invalid before this */
David Howells9b3f26c2009-04-03 16:42:41 +0100492#ifdef CONFIG_AFS_FSCACHE
493 struct fscache_cookie *cache; /* caching cookie */
David Howells08e0e7c2007-04-26 15:55:03 -0700494#endif
David Howellsfe342cf2018-04-09 21:12:31 +0100495 struct afs_permits __rcu *permit_cache; /* cache of permits so far obtained */
David Howellsd2ddc772017-11-02 15:27:50 +0000496 struct mutex io_lock; /* Lock for serialising I/O on this mutex */
David Howells260a9802007-04-26 15:59:35 -0700497 struct mutex validate_lock; /* lock for validating this vnode */
David Howells4343d002017-11-02 15:27:52 +0000498 spinlock_t wb_lock; /* lock for wb_keys */
David Howells08e0e7c2007-04-26 15:55:03 -0700499 spinlock_t lock; /* waitqueue/flags lock */
500 unsigned long flags;
David Howellsc435ee32017-11-02 15:27:49 +0000501#define AFS_VNODE_CB_PROMISED 0 /* Set if vnode has a callback promise */
David Howells260a9802007-04-26 15:59:35 -0700502#define AFS_VNODE_UNSET 1 /* set if vnode attributes not yet set */
David Howellsf3ddee82018-04-06 14:17:25 +0100503#define AFS_VNODE_DIR_VALID 2 /* Set if dir contents are valid */
David Howells08e0e7c2007-04-26 15:55:03 -0700504#define AFS_VNODE_ZAP_DATA 3 /* set if vnode's data should be invalidated */
505#define AFS_VNODE_DELETED 4 /* set if vnode deleted on server */
506#define AFS_VNODE_MOUNTPOINT 5 /* set if vnode is a mountpoint symlink */
David Howells0fafdc92017-11-13 16:59:50 +0000507#define AFS_VNODE_AUTOCELL 6 /* set if Vnode is an auto mount point */
508#define AFS_VNODE_PSEUDODIR 7 /* set if Vnode is a pseudo directory */
David Howells5a813272018-04-06 14:17:26 +0100509#define AFS_VNODE_NEW_CONTENT 8 /* Set if file has new content (create/trunc-0) */
David Howells08e0e7c2007-04-26 15:55:03 -0700510
David Howells4343d002017-11-02 15:27:52 +0000511 struct list_head wb_keys; /* List of keys available for writeback */
David Howellse8d6c552007-07-15 23:40:12 -0700512 struct list_head pending_locks; /* locks waiting to be granted */
513 struct list_head granted_locks; /* locks granted on this file */
514 struct delayed_work lock_work; /* work to be done in locking */
David Howells0fafdc92017-11-13 16:59:50 +0000515 struct key *lock_key; /* Key to be used in lock ops */
516 enum afs_lock_state lock_state : 8;
517 afs_lock_type_t lock_type : 8;
David Howells31143d52007-05-09 02:33:46 -0700518
David Howells08e0e7c2007-04-26 15:55:03 -0700519 /* outstanding callback notification on this file */
David Howellsc435ee32017-11-02 15:27:49 +0000520 struct afs_cb_interest *cb_interest; /* Server on which this resides */
521 unsigned int cb_s_break; /* Mass break counter on ->server */
522 unsigned int cb_break; /* Break counter on vnode */
523 seqlock_t cb_lock; /* Lock for ->cb_interest, ->status, ->cb_*break */
524
525 time64_t cb_expires_at; /* time at which callback expires */
David Howells08e0e7c2007-04-26 15:55:03 -0700526 unsigned cb_version; /* callback version */
David Howells08e0e7c2007-04-26 15:55:03 -0700527 afs_callback_type_t cb_type; /* type of callback */
David Howells08e0e7c2007-04-26 15:55:03 -0700528};
529
David Howells00d3b7a2007-04-26 15:57:07 -0700530/*
531 * cached security record for one user's attempt to access a vnode
532 */
533struct afs_permit {
534 struct key *key; /* RxRPC ticket holding a security context */
David Howellsbe080a62017-11-02 15:27:49 +0000535 afs_access_t access; /* CallerAccess value for this key */
David Howells00d3b7a2007-04-26 15:57:07 -0700536};
537
538/*
David Howellsbe080a62017-11-02 15:27:49 +0000539 * Immutable cache of CallerAccess records from attempts to access vnodes.
540 * These may be shared between multiple vnodes.
David Howells00d3b7a2007-04-26 15:57:07 -0700541 */
542struct afs_permits {
David Howellsbe080a62017-11-02 15:27:49 +0000543 struct rcu_head rcu;
544 struct hlist_node hash_node; /* Link in hash */
545 unsigned long h; /* Hash value for this permit list */
546 refcount_t usage;
547 unsigned short nr_permits; /* Number of records */
548 bool invalidated; /* Invalidated due to key change */
549 struct afs_permit permits[]; /* List of permits sorted by key pointer */
David Howells00d3b7a2007-04-26 15:57:07 -0700550};
551
David Howellsb908fe62007-04-26 15:58:17 -0700552/*
553 * record of one of a system's set of network interfaces
554 */
555struct afs_interface {
David Howellsb908fe62007-04-26 15:58:17 -0700556 struct in_addr address; /* IPv4 address bound to interface */
557 struct in_addr netmask; /* netmask applied to address */
558 unsigned mtu; /* MTU of interface */
559};
560
David Howells8b2a4642017-11-02 15:27:50 +0000561/*
562 * Cursor for iterating over a server's address list.
563 */
564struct afs_addr_cursor {
565 struct afs_addr_list *alist; /* Current address list (pins ref) */
566 struct sockaddr_rxrpc *addr;
David Howellsd2ddc772017-11-02 15:27:50 +0000567 u32 abort_code;
David Howells8b2a4642017-11-02 15:27:50 +0000568 unsigned short start; /* Starting point in alist->addrs[] */
569 unsigned short index; /* Wrapping offset from start to current addr */
570 short error;
571 bool begun; /* T if we've begun iteration */
572 bool responded; /* T if the current address responded */
573};
574
575/*
576 * Cursor for iterating over a set of fileservers.
577 */
578struct afs_fs_cursor {
579 struct afs_addr_cursor ac;
David Howellsd2ddc772017-11-02 15:27:50 +0000580 struct afs_vnode *vnode;
581 struct afs_server_list *server_list; /* Current server list (pins ref) */
582 struct afs_cb_interest *cbi; /* Server on which this resides (pins ref) */
583 struct key *key; /* Key for the server */
584 unsigned int cb_break; /* cb_break + cb_s_break before the call */
585 unsigned int cb_break_2; /* cb_break + cb_s_break (2nd vnode) */
586 unsigned char start; /* Initial index in server list */
587 unsigned char index; /* Number of servers tried beyond start */
588 unsigned short flags;
589#define AFS_FS_CURSOR_STOP 0x0001 /* Set to cease iteration */
590#define AFS_FS_CURSOR_VBUSY 0x0002 /* Set if seen VBUSY */
591#define AFS_FS_CURSOR_VMOVED 0x0004 /* Set if seen VMOVED */
592#define AFS_FS_CURSOR_VNOVOL 0x0008 /* Set if seen VNOVOL */
593#define AFS_FS_CURSOR_CUR_ONLY 0x0010 /* Set if current server only (file lock held) */
594#define AFS_FS_CURSOR_NO_VSLEEP 0x0020 /* Set to prevent sleep on VBUSY, VOFFLINE, ... */
David Howells8b2a4642017-11-02 15:27:50 +0000595};
596
David Howells402cb8d2018-04-04 13:41:28 +0100597/*
598 * Cache auxiliary data.
599 */
600struct afs_vnode_cache_aux {
601 u64 data_version;
602} __packed;
603
David Howells98bf40c2017-11-02 15:27:53 +0000604#include <trace/events/afs.h>
605
David Howells08e0e7c2007-04-26 15:55:03 -0700606/*****************************************************************************/
607/*
David Howells8b2a4642017-11-02 15:27:50 +0000608 * addr_list.c
609 */
610static inline struct afs_addr_list *afs_get_addrlist(struct afs_addr_list *alist)
611{
612 if (alist)
613 refcount_inc(&alist->usage);
614 return alist;
615}
616extern struct afs_addr_list *afs_alloc_addrlist(unsigned int,
617 unsigned short,
618 unsigned short);
619extern void afs_put_addrlist(struct afs_addr_list *);
620extern struct afs_addr_list *afs_parse_text_addrs(const char *, size_t, char,
621 unsigned short, unsigned short);
622extern struct afs_addr_list *afs_dns_query(struct afs_cell *, time64_t *);
623extern bool afs_iterate_addresses(struct afs_addr_cursor *);
624extern int afs_end_cursor(struct afs_addr_cursor *);
625extern int afs_set_vl_cursor(struct afs_addr_cursor *, struct afs_cell *);
626
David Howellsbf99a532017-11-02 15:27:51 +0000627extern void afs_merge_fs_addr4(struct afs_addr_list *, __be32, u16);
628extern void afs_merge_fs_addr6(struct afs_addr_list *, __be32 *, u16);
David Howellsd2ddc772017-11-02 15:27:50 +0000629
David Howells8b2a4642017-11-02 15:27:50 +0000630/*
David Howells9b3f26c2009-04-03 16:42:41 +0100631 * cache.c
632 */
633#ifdef CONFIG_AFS_FSCACHE
634extern struct fscache_netfs afs_cache_netfs;
635extern struct fscache_cookie_def afs_cell_cache_index_def;
David Howells9b3f26c2009-04-03 16:42:41 +0100636extern struct fscache_cookie_def afs_volume_cache_index_def;
637extern struct fscache_cookie_def afs_vnode_cache_index_def;
638#else
639#define afs_cell_cache_index_def (*(struct fscache_cookie_def *) NULL)
David Howells9b3f26c2009-04-03 16:42:41 +0100640#define afs_volume_cache_index_def (*(struct fscache_cookie_def *) NULL)
641#define afs_vnode_cache_index_def (*(struct fscache_cookie_def *) NULL)
642#endif
643
644/*
David Howells08e0e7c2007-04-26 15:55:03 -0700645 * callback.c
646 */
647extern void afs_init_callback_state(struct afs_server *);
David Howellsc435ee32017-11-02 15:27:49 +0000648extern void afs_break_callback(struct afs_vnode *);
David Howells5cf9dd52018-04-09 21:12:31 +0100649extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break*);
David Howellsc435ee32017-11-02 15:27:49 +0000650
David Howellsd2ddc772017-11-02 15:27:50 +0000651extern int afs_register_server_cb_interest(struct afs_vnode *, struct afs_server_entry *);
David Howellsc435ee32017-11-02 15:27:49 +0000652extern void afs_put_cb_interest(struct afs_net *, struct afs_cb_interest *);
David Howellsd2ddc772017-11-02 15:27:50 +0000653extern void afs_clear_callback_interests(struct afs_net *, struct afs_server_list *);
David Howellsc435ee32017-11-02 15:27:49 +0000654
655static inline struct afs_cb_interest *afs_get_cb_interest(struct afs_cb_interest *cbi)
656{
657 refcount_inc(&cbi->usage);
658 return cbi;
659}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660
661/*
662 * cell.c
663 */
David Howells989782d2017-11-02 15:27:50 +0000664extern int afs_cell_init(struct afs_net *, const char *);
665extern struct afs_cell *afs_lookup_cell_rcu(struct afs_net *, const char *, unsigned);
666extern struct afs_cell *afs_lookup_cell(struct afs_net *, const char *, unsigned,
667 const char *, bool);
David Howells8b2a4642017-11-02 15:27:50 +0000668extern struct afs_cell *afs_get_cell(struct afs_cell *);
David Howells9ed900b2017-11-02 15:27:46 +0000669extern void afs_put_cell(struct afs_net *, struct afs_cell *);
David Howells989782d2017-11-02 15:27:50 +0000670extern void afs_manage_cells(struct work_struct *);
671extern void afs_cells_timer(struct timer_list *);
David Howellsf044c882017-11-02 15:27:45 +0000672extern void __net_exit afs_cell_purge(struct afs_net *);
David Howells08e0e7c2007-04-26 15:55:03 -0700673
674/*
675 * cmservice.c
676 */
677extern bool afs_cm_incoming_call(struct afs_call *);
678
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679/*
680 * dir.c
681 */
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -0800682extern const struct file_operations afs_dir_file_operations;
David Howells4d673da2018-02-06 06:26:30 +0000683extern const struct inode_operations afs_dir_inode_operations;
David Howellsf3ddee82018-04-06 14:17:25 +0100684extern const struct address_space_operations afs_dir_aops;
David Howells4d673da2018-02-06 06:26:30 +0000685extern const struct dentry_operations afs_fs_dentry_operations;
686
David Howells66c7e1d2018-04-06 14:17:25 +0100687extern void afs_d_release(struct dentry *);
688
689/*
David Howells63a46812018-04-06 14:17:25 +0100690 * dir_edit.c
691 */
692extern void afs_edit_dir_add(struct afs_vnode *, struct qstr *, struct afs_fid *,
693 enum afs_edit_dir_reason);
694extern void afs_edit_dir_remove(struct afs_vnode *, struct qstr *, enum afs_edit_dir_reason);
695
696/*
David Howells66c7e1d2018-04-06 14:17:25 +0100697 * dynroot.c
698 */
699extern const struct file_operations afs_dynroot_file_operations;
700extern const struct inode_operations afs_dynroot_inode_operations;
701extern const struct dentry_operations afs_dynroot_dentry_operations;
702
703extern struct inode *afs_try_auto_mntpt(struct dentry *, struct inode *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704
705/*
706 * file.c
707 */
Christoph Hellwigf5e54d62006-06-28 04:26:44 -0700708extern const struct address_space_operations afs_fs_aops;
Arjan van de Ven754661f2007-02-12 00:55:38 -0800709extern const struct inode_operations afs_file_inode_operations;
David Howells00d3b7a2007-04-26 15:57:07 -0700710extern const struct file_operations afs_file_operations;
711
David Howells4343d002017-11-02 15:27:52 +0000712extern int afs_cache_wb_key(struct afs_vnode *, struct afs_file *);
713extern void afs_put_wb_key(struct afs_wb_key *);
David Howells00d3b7a2007-04-26 15:57:07 -0700714extern int afs_open(struct inode *, struct file *);
715extern int afs_release(struct inode *, struct file *);
David Howellsd2ddc772017-11-02 15:27:50 +0000716extern int afs_fetch_data(struct afs_vnode *, struct key *, struct afs_read *);
Al Virof6d335c2010-05-21 15:27:09 +0100717extern int afs_page_filler(void *, struct page *);
David Howells196ee9c2017-01-05 10:38:34 +0000718extern void afs_put_read(struct afs_read *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720/*
David Howellse8d6c552007-07-15 23:40:12 -0700721 * flock.c
722 */
David Howellsf044c882017-11-02 15:27:45 +0000723extern struct workqueue_struct *afs_lock_manager;
724
David Howellse8d6c552007-07-15 23:40:12 -0700725extern void afs_lock_work(struct work_struct *);
726extern void afs_lock_may_be_available(struct afs_vnode *);
727extern int afs_lock(struct file *, int, struct file_lock *);
728extern int afs_flock(struct file *, int, struct file_lock *);
729
730/*
David Howells08e0e7c2007-04-26 15:55:03 -0700731 * fsclient.c
732 */
David Howellsdd9fbcb2018-04-06 14:17:24 +0100733#define AFS_VNODE_NOT_YET_SET 0x01
734#define AFS_VNODE_META_CHANGED 0x02
735#define AFS_VNODE_DATA_CHANGED 0x04
736extern void afs_update_inode_from_status(struct afs_vnode *, struct afs_file_status *,
737 const afs_dataversion_t *, u8);
738
David Howells0c3a5ac2018-04-06 14:17:24 +0100739extern int afs_fs_fetch_file_status(struct afs_fs_cursor *, struct afs_volsync *, bool);
David Howellsd2ddc772017-11-02 15:27:50 +0000740extern int afs_fs_give_up_callbacks(struct afs_net *, struct afs_server *);
741extern int afs_fs_fetch_data(struct afs_fs_cursor *, struct afs_read *);
David Howells63a46812018-04-06 14:17:25 +0100742extern int afs_fs_create(struct afs_fs_cursor *, const char *, umode_t, u64,
David Howellsd2ddc772017-11-02 15:27:50 +0000743 struct afs_fid *, struct afs_file_status *, struct afs_callback *);
David Howells63a46812018-04-06 14:17:25 +0100744extern int afs_fs_remove(struct afs_fs_cursor *, const char *, bool, u64);
745extern int afs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *, u64);
746extern int afs_fs_symlink(struct afs_fs_cursor *, const char *, const char *, u64,
David Howellsd2ddc772017-11-02 15:27:50 +0000747 struct afs_fid *, struct afs_file_status *);
748extern int afs_fs_rename(struct afs_fs_cursor *, const char *,
David Howells63a46812018-04-06 14:17:25 +0100749 struct afs_vnode *, const char *, u64, u64);
David Howells4343d002017-11-02 15:27:52 +0000750extern int afs_fs_store_data(struct afs_fs_cursor *, struct address_space *,
David Howellsd2ddc772017-11-02 15:27:50 +0000751 pgoff_t, pgoff_t, unsigned, unsigned);
752extern int afs_fs_setattr(struct afs_fs_cursor *, struct iattr *);
753extern int afs_fs_get_volume_status(struct afs_fs_cursor *, struct afs_volume_status *);
754extern int afs_fs_set_lock(struct afs_fs_cursor *, afs_lock_type_t);
755extern int afs_fs_extend_lock(struct afs_fs_cursor *);
756extern int afs_fs_release_lock(struct afs_fs_cursor *);
757extern int afs_fs_give_up_all_callbacks(struct afs_net *, struct afs_server *,
758 struct afs_addr_cursor *, struct key *);
759extern int afs_fs_get_capabilities(struct afs_net *, struct afs_server *,
760 struct afs_addr_cursor *, struct key *);
David Howells5cf9dd52018-04-09 21:12:31 +0100761extern int afs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *,
762 struct afs_fid *, struct afs_file_status *,
763 struct afs_callback *, unsigned int,
764 struct afs_volsync *);
765extern int afs_fs_fetch_status(struct afs_fs_cursor *, struct afs_net *,
766 struct afs_fid *, struct afs_file_status *,
767 struct afs_callback *, struct afs_volsync *);
David Howells08e0e7c2007-04-26 15:55:03 -0700768
769/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 * inode.c
771 */
David Howells0c3a5ac2018-04-06 14:17:24 +0100772extern int afs_fetch_status(struct afs_vnode *, struct key *, bool);
David Howellsc435ee32017-11-02 15:27:49 +0000773extern int afs_iget5_test(struct inode *, void *);
David Howells4d673da2018-02-06 06:26:30 +0000774extern struct inode *afs_iget_pseudo_dir(struct super_block *, bool);
David Howells00d3b7a2007-04-26 15:57:07 -0700775extern struct inode *afs_iget(struct super_block *, struct key *,
David Howells260a9802007-04-26 15:59:35 -0700776 struct afs_fid *, struct afs_file_status *,
David Howellsd2ddc772017-11-02 15:27:50 +0000777 struct afs_callback *,
778 struct afs_cb_interest *);
David Howells416351f2007-05-09 02:33:45 -0700779extern void afs_zap_data(struct afs_vnode *);
David Howells260a9802007-04-26 15:59:35 -0700780extern int afs_validate(struct afs_vnode *, struct key *);
David Howellsa528d352017-01-31 16:46:22 +0000781extern int afs_getattr(const struct path *, struct kstat *, u32, unsigned int);
David Howells31143d52007-05-09 02:33:46 -0700782extern int afs_setattr(struct dentry *, struct iattr *);
Al Virob57922d2010-06-07 14:34:48 -0400783extern void afs_evict_inode(struct inode *);
wangleibec5eb62010-08-11 09:38:04 +0100784extern int afs_drop_inode(struct inode *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785
786/*
787 * main.c
788 */
Tejun Heo0ad53ee2011-01-14 15:56:37 +0000789extern struct workqueue_struct *afs_wq;
David Howellsf044c882017-11-02 15:27:45 +0000790
791static inline struct afs_net *afs_d2net(struct dentry *dentry)
792{
793 return &__afs_net;
794}
795
796static inline struct afs_net *afs_i2net(struct inode *inode)
797{
798 return &__afs_net;
799}
800
801static inline struct afs_net *afs_v2net(struct afs_vnode *vnode)
802{
803 return &__afs_net;
804}
805
806static inline struct afs_net *afs_sock2net(struct sock *sk)
807{
808 return &__afs_net;
809}
810
811static inline struct afs_net *afs_get_net(struct afs_net *net)
812{
813 return net;
814}
815
816static inline void afs_put_net(struct afs_net *net)
817{
818}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819
David Howellsd55b4da2018-04-06 14:17:24 +0100820static inline void __afs_stat(atomic_t *s)
821{
822 atomic_inc(s);
823}
824
825#define afs_stat_v(vnode, n) __afs_stat(&afs_v2net(vnode)->n)
826
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827/*
David Howells08e0e7c2007-04-26 15:55:03 -0700828 * misc.c
829 */
830extern int afs_abort_to_error(u32);
831
832/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 * mntpt.c
834 */
Arjan van de Ven754661f2007-02-12 00:55:38 -0800835extern const struct inode_operations afs_mntpt_inode_operations;
wangleibec5eb62010-08-11 09:38:04 +0100836extern const struct inode_operations afs_autocell_inode_operations;
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -0800837extern const struct file_operations afs_mntpt_file_operations;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838
David Howellsd18610b2011-01-14 19:04:05 +0000839extern struct vfsmount *afs_d_automount(struct path *);
David Howells08e0e7c2007-04-26 15:55:03 -0700840extern void afs_mntpt_kill_timer(void);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841
842/*
Arnd Bergmannb4db2b32017-02-10 16:34:07 +0000843 * netdevices.c
844 */
845extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool);
846
847/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 * proc.c
849 */
David Howellsf044c882017-11-02 15:27:45 +0000850extern int __net_init afs_proc_init(struct afs_net *);
851extern void __net_exit afs_proc_cleanup(struct afs_net *);
852extern int afs_proc_cell_setup(struct afs_net *, struct afs_cell *);
853extern void afs_proc_cell_remove(struct afs_net *, struct afs_cell *);
David Howells6f8880d2018-04-09 21:12:31 +0100854extern void afs_put_sysnames(struct afs_sysnames *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855
David Howells08e0e7c2007-04-26 15:55:03 -0700856/*
David Howellsd2ddc772017-11-02 15:27:50 +0000857 * rotate.c
858 */
859extern bool afs_begin_vnode_operation(struct afs_fs_cursor *, struct afs_vnode *,
860 struct key *);
861extern bool afs_select_fileserver(struct afs_fs_cursor *);
862extern bool afs_select_current_fileserver(struct afs_fs_cursor *);
863extern int afs_end_vnode_operation(struct afs_fs_cursor *);
864
865/*
David Howells08e0e7c2007-04-26 15:55:03 -0700866 * rxrpc.c
867 */
David Howellsf044c882017-11-02 15:27:45 +0000868extern struct workqueue_struct *afs_async_calls;
David Howells8324f0b2016-08-30 09:49:29 +0100869
David Howellsf044c882017-11-02 15:27:45 +0000870extern int __net_init afs_open_socket(struct afs_net *);
871extern void __net_exit afs_close_socket(struct afs_net *);
872extern void afs_charge_preallocation(struct work_struct *);
David Howells341f7412017-01-05 10:38:36 +0000873extern void afs_put_call(struct afs_call *);
874extern int afs_queue_call_work(struct afs_call *);
David Howells8b2a4642017-11-02 15:27:50 +0000875extern long afs_make_call(struct afs_addr_cursor *, struct afs_call *, gfp_t, bool);
David Howellsf044c882017-11-02 15:27:45 +0000876extern struct afs_call *afs_alloc_flat_call(struct afs_net *,
877 const struct afs_call_type *,
David Howells08e0e7c2007-04-26 15:55:03 -0700878 size_t, size_t);
879extern void afs_flat_call_destructor(struct afs_call *);
David Howells08e0e7c2007-04-26 15:55:03 -0700880extern void afs_send_empty_reply(struct afs_call *);
David Howellsb908fe62007-04-26 15:58:17 -0700881extern void afs_send_simple_reply(struct afs_call *, const void *, size_t);
David Howellsd0016482016-08-30 20:42:14 +0100882extern int afs_extract_data(struct afs_call *, void *, size_t, bool);
David Howells5f702c82018-04-06 14:17:25 +0100883extern int afs_protocol_error(struct afs_call *, int);
David Howells08e0e7c2007-04-26 15:55:03 -0700884
David Howellsd0016482016-08-30 20:42:14 +0100885static inline int afs_transfer_reply(struct afs_call *call)
David Howells372ee162016-08-03 14:11:40 +0100886{
David Howellsd0016482016-08-30 20:42:14 +0100887 return afs_extract_data(call, call->buffer, call->reply_max, false);
David Howells372ee162016-08-03 14:11:40 +0100888}
889
David Howells98bf40c2017-11-02 15:27:53 +0000890static inline bool afs_check_call_state(struct afs_call *call,
891 enum afs_call_state state)
892{
893 return READ_ONCE(call->state) == state;
894}
895
896static inline bool afs_set_call_state(struct afs_call *call,
897 enum afs_call_state from,
898 enum afs_call_state to)
899{
900 bool ok = false;
901
902 spin_lock_bh(&call->state_lock);
903 if (call->state == from) {
904 call->state = to;
905 trace_afs_call_state(call, from, to, 0, 0);
906 ok = true;
907 }
908 spin_unlock_bh(&call->state_lock);
909 return ok;
910}
911
912static inline void afs_set_call_complete(struct afs_call *call,
913 int error, u32 remote_abort)
914{
915 enum afs_call_state state;
916 bool ok = false;
917
918 spin_lock_bh(&call->state_lock);
919 state = call->state;
920 if (state != AFS_CALL_COMPLETE) {
921 call->abort_code = remote_abort;
922 call->error = error;
923 call->state = AFS_CALL_COMPLETE;
924 trace_afs_call_state(call, state, AFS_CALL_COMPLETE,
925 error, remote_abort);
926 ok = true;
927 }
928 spin_unlock_bh(&call->state_lock);
929 if (ok)
930 trace_afs_call_done(call);
931}
932
David Howells08e0e7c2007-04-26 15:55:03 -0700933/*
David Howells00d3b7a2007-04-26 15:57:07 -0700934 * security.c
935 */
David Howellsbe080a62017-11-02 15:27:49 +0000936extern void afs_put_permits(struct afs_permits *);
David Howells00d3b7a2007-04-26 15:57:07 -0700937extern void afs_clear_permits(struct afs_vnode *);
David Howellsbe080a62017-11-02 15:27:49 +0000938extern void afs_cache_permit(struct afs_vnode *, struct key *, unsigned int);
David Howells416351f2007-05-09 02:33:45 -0700939extern void afs_zap_permits(struct rcu_head *);
David Howells00d3b7a2007-04-26 15:57:07 -0700940extern struct key *afs_request_key(struct afs_cell *);
David Howells0fafdc92017-11-13 16:59:50 +0000941extern int afs_check_permit(struct afs_vnode *, struct key *, afs_access_t *);
Al Viro10556cb2011-06-20 19:28:19 -0400942extern int afs_permission(struct inode *, int);
David Howellsbe080a62017-11-02 15:27:49 +0000943extern void __exit afs_clean_up_permit_cache(void);
David Howells00d3b7a2007-04-26 15:57:07 -0700944
945/*
David Howells08e0e7c2007-04-26 15:55:03 -0700946 * server.c
947 */
948extern spinlock_t afs_server_peer_lock;
949
David Howellsc435ee32017-11-02 15:27:49 +0000950static inline struct afs_server *afs_get_server(struct afs_server *server)
951{
952 atomic_inc(&server->usage);
953 return server;
954}
David Howells08e0e7c2007-04-26 15:55:03 -0700955
David Howellsf044c882017-11-02 15:27:45 +0000956extern struct afs_server *afs_find_server(struct afs_net *,
957 const struct sockaddr_rxrpc *);
David Howellsd2ddc772017-11-02 15:27:50 +0000958extern struct afs_server *afs_find_server_by_uuid(struct afs_net *, const uuid_t *);
959extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *);
David Howells9ed900b2017-11-02 15:27:46 +0000960extern void afs_put_server(struct afs_net *, struct afs_server *);
David Howellsd2ddc772017-11-02 15:27:50 +0000961extern void afs_manage_servers(struct work_struct *);
962extern void afs_servers_timer(struct timer_list *);
David Howellsf044c882017-11-02 15:27:45 +0000963extern void __net_exit afs_purge_servers(struct afs_net *);
David Howellsd2ddc772017-11-02 15:27:50 +0000964extern bool afs_probe_fileserver(struct afs_fs_cursor *);
965extern bool afs_check_server_record(struct afs_fs_cursor *, struct afs_server *);
966
967/*
968 * server_list.c
969 */
970static inline struct afs_server_list *afs_get_serverlist(struct afs_server_list *slist)
971{
972 refcount_inc(&slist->usage);
973 return slist;
974}
975
976extern void afs_put_serverlist(struct afs_net *, struct afs_server_list *);
977extern struct afs_server_list *afs_alloc_server_list(struct afs_cell *, struct key *,
978 struct afs_vldb_entry *,
979 u8);
980extern bool afs_annotate_server_list(struct afs_server_list *, struct afs_server_list *);
David Howells08e0e7c2007-04-26 15:55:03 -0700981
982/*
David Howells00d3b7a2007-04-26 15:57:07 -0700983 * super.c
984 */
David Howellsf044c882017-11-02 15:27:45 +0000985extern int __init afs_fs_init(void);
986extern void __exit afs_fs_exit(void);
David Howells00d3b7a2007-04-26 15:57:07 -0700987
988/*
David Howells08e0e7c2007-04-26 15:55:03 -0700989 * vlclient.c
990 */
David Howellsd2ddc772017-11-02 15:27:50 +0000991extern struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_net *,
992 struct afs_addr_cursor *,
993 struct key *, const char *, int);
994extern struct afs_addr_list *afs_vl_get_addrs_u(struct afs_net *, struct afs_addr_cursor *,
995 struct key *, const uuid_t *);
David Howellsbf99a532017-11-02 15:27:51 +0000996extern int afs_vl_get_capabilities(struct afs_net *, struct afs_addr_cursor *, struct key *);
997extern struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_net *, struct afs_addr_cursor *,
998 struct key *, const uuid_t *);
David Howells08e0e7c2007-04-26 15:55:03 -0700999
1000/*
1001 * volume.c
1002 */
David Howellsd2ddc772017-11-02 15:27:50 +00001003static inline struct afs_volume *__afs_get_volume(struct afs_volume *volume)
David Howells49566f62017-11-02 15:27:46 +00001004{
1005 if (volume)
1006 atomic_inc(&volume->usage);
1007 return volume;
1008}
David Howells08e0e7c2007-04-26 15:55:03 -07001009
David Howellsd2ddc772017-11-02 15:27:50 +00001010extern struct afs_volume *afs_create_volume(struct afs_mount_params *);
1011extern void afs_activate_volume(struct afs_volume *);
1012extern void afs_deactivate_volume(struct afs_volume *);
David Howells9ed900b2017-11-02 15:27:46 +00001013extern void afs_put_volume(struct afs_cell *, struct afs_volume *);
David Howellsd2ddc772017-11-02 15:27:50 +00001014extern int afs_check_volume_status(struct afs_volume *, struct key *);
David Howells08e0e7c2007-04-26 15:55:03 -07001015
David Howells31143d52007-05-09 02:33:46 -07001016/*
1017 * write.c
1018 */
1019extern int afs_set_page_dirty(struct page *);
Nick Piggin15b46502008-10-15 22:04:32 -07001020extern int afs_write_begin(struct file *file, struct address_space *mapping,
1021 loff_t pos, unsigned len, unsigned flags,
1022 struct page **pagep, void **fsdata);
1023extern int afs_write_end(struct file *file, struct address_space *mapping,
1024 loff_t pos, unsigned len, unsigned copied,
1025 struct page *page, void *fsdata);
David Howells31143d52007-05-09 02:33:46 -07001026extern int afs_writepage(struct page *, struct writeback_control *);
1027extern int afs_writepages(struct address_space *, struct writeback_control *);
David Howells31143d52007-05-09 02:33:46 -07001028extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *);
Al Viro50b55512014-04-03 14:13:46 -04001029extern ssize_t afs_file_write(struct kiocb *, struct iov_iter *);
Josef Bacik02c24a82011-07-16 20:44:56 -04001030extern int afs_fsync(struct file *, loff_t, loff_t, int);
David Howells1cf7a152017-11-02 15:27:52 +00001031extern int afs_page_mkwrite(struct vm_fault *);
David Howells4343d002017-11-02 15:27:52 +00001032extern void afs_prune_wb_keys(struct afs_vnode *);
1033extern int afs_launder_page(struct page *);
David Howells31143d52007-05-09 02:33:46 -07001034
David Howellsd3e3b7ea2017-07-06 15:50:27 +01001035/*
1036 * xattr.c
1037 */
1038extern const struct xattr_handler *afs_xattr_handlers[];
1039extern ssize_t afs_listxattr(struct dentry *, char *, size_t);
David Howells31143d52007-05-09 02:33:46 -07001040
David Howellsd2ddc772017-11-02 15:27:50 +00001041
1042/*
1043 * Miscellaneous inline functions.
1044 */
1045static inline struct afs_vnode *AFS_FS_I(struct inode *inode)
1046{
1047 return container_of(inode, struct afs_vnode, vfs_inode);
1048}
1049
1050static inline struct inode *AFS_VNODE_TO_I(struct afs_vnode *vnode)
1051{
1052 return &vnode->vfs_inode;
1053}
1054
1055static inline void afs_vnode_commit_status(struct afs_fs_cursor *fc,
1056 struct afs_vnode *vnode,
1057 unsigned int cb_break)
1058{
1059 if (fc->ac.error == 0)
1060 afs_cache_permit(vnode, fc->key, cb_break);
1061}
1062
1063static inline void afs_check_for_remote_deletion(struct afs_fs_cursor *fc,
1064 struct afs_vnode *vnode)
1065{
1066 if (fc->ac.error == -ENOENT) {
1067 set_bit(AFS_VNODE_DELETED, &vnode->flags);
1068 afs_break_callback(vnode);
1069 }
1070}
1071
1072
David Howells08e0e7c2007-04-26 15:55:03 -07001073/*****************************************************************************/
1074/*
1075 * debug tracing
1076 */
1077extern unsigned afs_debug;
1078
1079#define dbgprintk(FMT,...) \
Sven Schnellead16df82008-04-03 10:44:01 +01001080 printk("[%-6.6s] "FMT"\n", current->comm ,##__VA_ARGS__)
David Howells08e0e7c2007-04-26 15:55:03 -07001081
Harvey Harrison530b6412008-04-30 00:55:09 -07001082#define kenter(FMT,...) dbgprintk("==> %s("FMT")",__func__ ,##__VA_ARGS__)
1083#define kleave(FMT,...) dbgprintk("<== %s()"FMT"",__func__ ,##__VA_ARGS__)
David Howells08e0e7c2007-04-26 15:55:03 -07001084#define kdebug(FMT,...) dbgprintk(" "FMT ,##__VA_ARGS__)
1085
1086
1087#if defined(__KDEBUG)
1088#define _enter(FMT,...) kenter(FMT,##__VA_ARGS__)
1089#define _leave(FMT,...) kleave(FMT,##__VA_ARGS__)
1090#define _debug(FMT,...) kdebug(FMT,##__VA_ARGS__)
1091
1092#elif defined(CONFIG_AFS_DEBUG)
1093#define AFS_DEBUG_KENTER 0x01
1094#define AFS_DEBUG_KLEAVE 0x02
1095#define AFS_DEBUG_KDEBUG 0x04
1096
1097#define _enter(FMT,...) \
1098do { \
1099 if (unlikely(afs_debug & AFS_DEBUG_KENTER)) \
1100 kenter(FMT,##__VA_ARGS__); \
1101} while (0)
1102
1103#define _leave(FMT,...) \
1104do { \
1105 if (unlikely(afs_debug & AFS_DEBUG_KLEAVE)) \
1106 kleave(FMT,##__VA_ARGS__); \
1107} while (0)
1108
1109#define _debug(FMT,...) \
1110do { \
1111 if (unlikely(afs_debug & AFS_DEBUG_KDEBUG)) \
1112 kdebug(FMT,##__VA_ARGS__); \
1113} while (0)
1114
1115#else
David Howells12fdff32010-08-12 16:54:57 +01001116#define _enter(FMT,...) no_printk("==> %s("FMT")",__func__ ,##__VA_ARGS__)
1117#define _leave(FMT,...) no_printk("<== %s()"FMT"",__func__ ,##__VA_ARGS__)
1118#define _debug(FMT,...) no_printk(" "FMT ,##__VA_ARGS__)
David Howells08e0e7c2007-04-26 15:55:03 -07001119#endif
1120
1121/*
1122 * debug assertion checking
1123 */
1124#if 1 // defined(__KDEBUGALL)
1125
1126#define ASSERT(X) \
1127do { \
1128 if (unlikely(!(X))) { \
1129 printk(KERN_ERR "\n"); \
1130 printk(KERN_ERR "AFS: Assertion failed\n"); \
1131 BUG(); \
1132 } \
1133} while(0)
1134
1135#define ASSERTCMP(X, OP, Y) \
1136do { \
1137 if (unlikely(!((X) OP (Y)))) { \
1138 printk(KERN_ERR "\n"); \
1139 printk(KERN_ERR "AFS: Assertion failed\n"); \
1140 printk(KERN_ERR "%lu " #OP " %lu is false\n", \
1141 (unsigned long)(X), (unsigned long)(Y)); \
1142 printk(KERN_ERR "0x%lx " #OP " 0x%lx is false\n", \
1143 (unsigned long)(X), (unsigned long)(Y)); \
1144 BUG(); \
1145 } \
1146} while(0)
1147
David Howells416351f2007-05-09 02:33:45 -07001148#define ASSERTRANGE(L, OP1, N, OP2, H) \
1149do { \
1150 if (unlikely(!((L) OP1 (N)) || !((N) OP2 (H)))) { \
1151 printk(KERN_ERR "\n"); \
1152 printk(KERN_ERR "AFS: Assertion failed\n"); \
1153 printk(KERN_ERR "%lu "#OP1" %lu "#OP2" %lu is false\n", \
1154 (unsigned long)(L), (unsigned long)(N), \
1155 (unsigned long)(H)); \
1156 printk(KERN_ERR "0x%lx "#OP1" 0x%lx "#OP2" 0x%lx is false\n", \
1157 (unsigned long)(L), (unsigned long)(N), \
1158 (unsigned long)(H)); \
1159 BUG(); \
1160 } \
1161} while(0)
1162
David Howells08e0e7c2007-04-26 15:55:03 -07001163#define ASSERTIF(C, X) \
1164do { \
1165 if (unlikely((C) && !(X))) { \
1166 printk(KERN_ERR "\n"); \
1167 printk(KERN_ERR "AFS: Assertion failed\n"); \
1168 BUG(); \
1169 } \
1170} while(0)
1171
1172#define ASSERTIFCMP(C, X, OP, Y) \
1173do { \
1174 if (unlikely((C) && !((X) OP (Y)))) { \
1175 printk(KERN_ERR "\n"); \
1176 printk(KERN_ERR "AFS: Assertion failed\n"); \
1177 printk(KERN_ERR "%lu " #OP " %lu is false\n", \
1178 (unsigned long)(X), (unsigned long)(Y)); \
1179 printk(KERN_ERR "0x%lx " #OP " 0x%lx is false\n", \
1180 (unsigned long)(X), (unsigned long)(Y)); \
1181 BUG(); \
1182 } \
1183} while(0)
1184
1185#else
1186
1187#define ASSERT(X) \
1188do { \
1189} while(0)
1190
1191#define ASSERTCMP(X, OP, Y) \
1192do { \
1193} while(0)
1194
David Howells416351f2007-05-09 02:33:45 -07001195#define ASSERTRANGE(L, OP1, N, OP2, H) \
1196do { \
1197} while(0)
1198
David Howells08e0e7c2007-04-26 15:55:03 -07001199#define ASSERTIF(C, X) \
1200do { \
1201} while(0)
1202
1203#define ASSERTIFCMP(C, X, OP, Y) \
1204do { \
1205} while(0)
1206
1207#endif /* __KDEBUGALL */