12874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */
2ec26815aSDavid Howells/* internal AFS stuff
31da177e4SLinus Torvalds *
408e0e7c8SDavid Howells * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
51da177e4SLinus Torvalds * Written by David Howells (dhowells@redhat.com)
61da177e4SLinus Torvalds */
71da177e4SLinus Torvalds
81da177e4SLinus Torvalds#include <linux/compiler.h>
91da177e4SLinus Torvalds#include <linux/kernel.h>
108a79790bSTina Ruchandani#include <linux/ktime.h>
111da177e4SLinus Torvalds#include <linux/fs.h>
121da177e4SLinus Torvalds#include <linux/pagemap.h>
1308e0e7c8SDavid Howells#include <linux/rxrpc.h>
1400d3b7a4SDavid Howells#include <linux/key.h>
15e8edc6e0SAlexey Dobriyan#include <linux/workqueue.h>
1600c541eaSAndrew Morton#include <linux/sched.h>
1780e50be4SChristoph Hellwig#include <linux/fscache.h>
18e1da0222SJens Axboe#include <linux/backing-dev.h>
19ff548773SDavid Howells#include <linux/uuid.h>
200722f186SSouptick Joarder#include <linux/mm_types.h>
210a5143f2SDavid Howells#include <linux/dns_resolver.h>
22f044c884SDavid Howells#include <net/net_namespace.h>
235b86d4ffSDavid Howells#include <net/netns/generic.h>
245b86d4ffSDavid Howells#include <net/sock.h>
258324f0bcSDavid Howells#include <net/af_rxrpc.h>
2600c541eaSAndrew Morton
2708e0e7c8SDavid Howells#include "afs.h"
2808e0e7c8SDavid Howells#include "afs_vl.h"
2908e0e7c8SDavid Howells
3008e0e7c8SDavid Howells#define AFS_CELL_MAX_ADDRS 15
3108e0e7c8SDavid Howells
3231143d5dSDavid Howellsstruct pagevec;
3308e0e7c8SDavid Howellsstruct afs_call;
34c4508464SDavid Howellsstruct afs_vnode;
3508e0e7c8SDavid Howells
366c6c1d63SDavid Howells/*
376c6c1d63SDavid Howells * Partial file-locking emulation mode.  (The problem being that AFS3 only
386c6c1d63SDavid Howells * allows whole-file locks and no upgrading/downgrading).
396c6c1d63SDavid Howells */
406c6c1d63SDavid Howellsenum afs_flock_mode {
416c6c1d63SDavid Howells	afs_flock_mode_unset,
426c6c1d63SDavid Howells	afs_flock_mode_local,	/* Local locking only */
436c6c1d63SDavid Howells	afs_flock_mode_openafs,	/* Don't get server lock for a partial lock */
446c6c1d63SDavid Howells	afs_flock_mode_strict,	/* Always get a server lock for a partial lock */
456c6c1d63SDavid Howells	afs_flock_mode_write,	/* Get an exclusive server lock for a partial lock */
466c6c1d63SDavid Howells};
476c6c1d63SDavid Howells
4813fcc683SDavid Howellsstruct afs_fs_context {
4900d3b7a4SDavid Howells	bool			force;		/* T to force cell type */
50bec5eb61Swanglei	bool			autocell;	/* T if set auto mount operation */
514d673da1SDavid Howells	bool			dyn_root;	/* T if dynamic root */
5213fcc683SDavid Howells	bool			no_cell;	/* T if the source is "none" (for dynroot) */
536c6c1d63SDavid Howells	enum afs_flock_mode	flock_mode;	/* Partial file-locking emulation mode */
5400d3b7a4SDavid Howells	afs_voltype_t		type;		/* type of volume requested */
5513fcc683SDavid Howells	unsigned int		volnamesz;	/* size of volume name */
5600d3b7a4SDavid Howells	const char		*volname;	/* name of volume to mount */
575b86d4ffSDavid Howells	struct afs_net		*net;		/* the AFS net namespace stuff */
5800d3b7a4SDavid Howells	struct afs_cell		*cell;		/* cell in which to find volume */
5900d3b7a4SDavid Howells	struct afs_volume	*volume;	/* volume record */
6000d3b7a4SDavid Howells	struct key		*key;		/* key to use for secure mounting */
6100d3b7a4SDavid Howells};
6200d3b7a4SDavid Howells
638e8d7f13SDavid Howellsenum afs_call_state {
6498bf40cdSDavid Howells	AFS_CALL_CL_REQUESTING,		/* Client: Request is being sent */
6598bf40cdSDavid Howells	AFS_CALL_CL_AWAIT_REPLY,	/* Client: Awaiting reply */
6698bf40cdSDavid Howells	AFS_CALL_CL_PROC_REPLY,		/* Client: rxrpc call complete; processing reply */
6798bf40cdSDavid Howells	AFS_CALL_SV_AWAIT_OP_ID,	/* Server: Awaiting op ID */
6898bf40cdSDavid Howells	AFS_CALL_SV_AWAIT_REQUEST,	/* Server: Awaiting request data */
6998bf40cdSDavid Howells	AFS_CALL_SV_REPLYING,		/* Server: Replying */
7098bf40cdSDavid Howells	AFS_CALL_SV_AWAIT_ACK,		/* Server: Awaiting final ACK */
7198bf40cdSDavid Howells	AFS_CALL_COMPLETE,		/* Completed or failed */
728e8d7f13SDavid Howells};
73f044c884SDavid Howells
748b2a464cSDavid Howells/*
758b2a464cSDavid Howells * List of server addresses.
768b2a464cSDavid Howells */
778b2a464cSDavid Howellsstruct afs_addr_list {
78ddd2b85fSJann Horn	struct rcu_head		rcu;
798b2a464cSDavid Howells	refcount_t		usage;
80d2ddc776SDavid Howells	u32			version;	/* Version */
8168eb64c3SDavid Howells	unsigned char		max_addrs;
8268eb64c3SDavid Howells	unsigned char		nr_addrs;
833bf0fb6fSDavid Howells	unsigned char		preferred;	/* Preferred address */
8468eb64c3SDavid Howells	unsigned char		nr_ipv4;	/* Number of IPv4 addresses */
850a5143f2SDavid Howells	enum dns_record_source	source:8;
860a5143f2SDavid Howells	enum dns_lookup_status	status:8;
873bf0fb6fSDavid Howells	unsigned long		failed;		/* Mask of addrs that failed locally/ICMP */
883bf0fb6fSDavid Howells	unsigned long		responded;	/* Mask of addrs that responded */
898b2a464cSDavid Howells	struct sockaddr_rxrpc	addrs[];
9068eb64c3SDavid Howells#define AFS_MAX_ADDRESSES ((unsigned int)(sizeof(unsigned long) * 8))
918b2a464cSDavid Howells};
928b2a464cSDavid Howells
9308e0e7c8SDavid Howells/*
9408e0e7c8SDavid Howells * a record of an in-progress RxRPC call
9508e0e7c8SDavid Howells */
9608e0e7c8SDavid Howellsstruct afs_call {
9708e0e7c8SDavid Howells	const struct afs_call_type *type;	/* type of call */
983bf0fb6fSDavid Howells	struct afs_addr_list	*alist;		/* Address is alist[addr_ix] */
9908e0e7c8SDavid Howells	wait_queue_head_t	waitq;		/* processes awaiting completion */
100341f741fSDavid Howells	struct work_struct	async_work;	/* async I/O processor */
10108e0e7c8SDavid Howells	struct work_struct	work;		/* actual work processor */
10208e0e7c8SDavid Howells	struct rxrpc_call	*rxcall;	/* RxRPC call handle */
10308e0e7c8SDavid Howells	struct key		*key;		/* security for this call */
104f044c884SDavid Howells	struct afs_net		*net;		/* The network namespace */
105a6853b9cSDavid Howells	struct afs_server	*server;	/* The fileserver record if fs op (pins ref) */
106a6853b9cSDavid Howells	struct afs_vlserver	*vlserver;	/* The vlserver record if vl op */
10708e0e7c8SDavid Howells	void			*request;	/* request data (first part) */
108f105da1aSDavid Howells	size_t			iov_len;	/* Size of *iter to be used */
109fc276122SDavid Howells	struct iov_iter		def_iter;	/* Default buffer/data iterator */
110bd80d8a8SDavid Howells	struct iov_iter		*write_iter;	/* Iterator defining write to be made */
111fc276122SDavid Howells	struct iov_iter		*iter;		/* Iterator currently in use */
112fc276122SDavid Howells	union {	/* Convenience for ->def_iter */
11312bdcf33SDavid Howells		struct kvec	kvec[1];
11412bdcf33SDavid Howells		struct bio_vec	bvec[1];
11512bdcf33SDavid Howells	};
11608e0e7c8SDavid Howells	void			*buffer;	/* reply receive buffer */
117ffba718eSDavid Howells	union {
118ffba718eSDavid Howells		long			ret0;	/* Value to reply with instead of 0 */
119ffba718eSDavid Howells		struct afs_addr_list	*ret_alist;
120ffba718eSDavid Howells		struct afs_vldb_entry	*ret_vldb;
121c3e9f888SDavid Howells		char			*ret_str;
122ffba718eSDavid Howells	};
123e49c7b2fSDavid Howells	struct afs_operation	*op;
124ffba718eSDavid Howells	unsigned int		server_index;
125341f741fSDavid Howells	atomic_t		usage;
1268e8d7f13SDavid Howells	enum afs_call_state	state;
12798bf40cdSDavid Howells	spinlock_t		state_lock;
12808e0e7c8SDavid Howells	int			error;		/* error code */
129d001648eSDavid Howells	u32			abort_code;	/* Remote abort ID or 0 */
13094f699c9SDavid Howells	unsigned int		max_lifespan;	/* Maximum lifespan to set if not 0 */
13108e0e7c8SDavid Howells	unsigned		request_size;	/* size of request data */
13208e0e7c8SDavid Howells	unsigned		reply_max;	/* maximum size of reply */
133e49c7b2fSDavid Howells	unsigned		count2;		/* count used in unmarshalling */
13408e0e7c8SDavid Howells	unsigned char		unmarshall;	/* unmarshalling phase */
1353bf0fb6fSDavid Howells	unsigned char		addr_ix;	/* Address in ->alist */
136dde9f095SDavid Howells	bool			drop_ref;	/* T if need to drop ref for incoming call */
137d001648eSDavid Howells	bool			need_attention;	/* T if RxRPC poked us */
13856ff9c83SDavid Howells	bool			async;		/* T if asynchronous */
139a68f4a27SDavid Howells	bool			upgrade;	/* T to request service upgrade */
1404571577fSDavid Howells	bool			have_reply_time; /* T if have got reply_time */
14120b8391fSDavid Howells	bool			intr;		/* T if interruptible */
14238355eecSDavid Howells	bool			unmarshalling_error; /* T if an unmarshalling error occurred */
143bf99a53cSDavid Howells	u16			service_id;	/* Actual service ID (after upgrade) */
144a25e21f0SDavid Howells	unsigned int		debug_id;	/* Trace ID */
14550a2c953SDavid Howells	u32			operation_ID;	/* operation ID for an incoming call */
14608e0e7c8SDavid Howells	u32			count;		/* count for use in unmarshalling */
14712bdcf33SDavid Howells	union {					/* place to extract temporary data */
14812bdcf33SDavid Howells		struct {
14912bdcf33SDavid Howells			__be32	tmp_u;
15012bdcf33SDavid Howells			__be32	tmp;
15112bdcf33SDavid Howells		} __attribute__((packed));
15212bdcf33SDavid Howells		__be64		tmp64;
15312bdcf33SDavid Howells	};
15412d8e95aSDavid Howells	ktime_t			reply_time;	/* Time of first reply packet */
15508e0e7c8SDavid Howells};
15608e0e7c8SDavid Howells
15708e0e7c8SDavid Howellsstruct afs_call_type {
15800d3b7a4SDavid Howells	const char *name;
159025db80cSDavid Howells	unsigned int op; /* Really enum afs_fs_operation */
16000d3b7a4SDavid Howells
16108e0e7c8SDavid Howells	/* deliver request or reply data to an call
16208e0e7c8SDavid Howells	 * - returning an error will cause the call to be aborted
16308e0e7c8SDavid Howells	 */
164d001648eSDavid Howells	int (*deliver)(struct afs_call *call);
16508e0e7c8SDavid Howells
16608e0e7c8SDavid Howells	/* clean up a call */
16708e0e7c8SDavid Howells	void (*destructor)(struct afs_call *call);
168341f741fSDavid Howells
169341f741fSDavid Howells	/* Work function */
170341f741fSDavid Howells	void (*work)(struct work_struct *work);
1713bf0fb6fSDavid Howells
1723bf0fb6fSDavid Howells	/* Call done function (gets called immediately on success or failure) */
1733bf0fb6fSDavid Howells	void (*done)(struct afs_call *call);
17408e0e7c8SDavid Howells};
17508e0e7c8SDavid Howells
1764343d008SDavid Howells/*
1774343d008SDavid Howells * Key available for writeback on a file.
1784343d008SDavid Howells */
1794343d008SDavid Howellsstruct afs_wb_key {
1804343d008SDavid Howells	refcount_t		usage;
1814343d008SDavid Howells	struct key		*key;
1824343d008SDavid Howells	struct list_head	vnode_link;	/* Link in vnode->wb_keys */
1834343d008SDavid Howells};
1844343d008SDavid Howells
185215804a9SDavid Howells/*
186215804a9SDavid Howells * AFS open file information record.  Pointed to by file->private_data.
187215804a9SDavid Howells */
188215804a9SDavid Howellsstruct afs_file {
189215804a9SDavid Howells	struct key		*key;		/* The key this file was opened with */
1904343d008SDavid Howells	struct afs_wb_key	*wb;		/* Writeback key record for this file */
191215804a9SDavid Howells};
192215804a9SDavid Howells
193215804a9SDavid Howellsstatic inline struct key *afs_file_key(struct file *file)
194215804a9SDavid Howells{
195215804a9SDavid Howells	struct afs_file *af = file->private_data;
196215804a9SDavid Howells
197215804a9SDavid Howells	return af->key;
198215804a9SDavid Howells}
199215804a9SDavid Howells
200196ee9cdSDavid Howells/*
201196ee9cdSDavid Howells * Record of an outstanding read operation on a vnode.
202196ee9cdSDavid Howells */
203196ee9cdSDavid Howellsstruct afs_read {
204196ee9cdSDavid Howells	loff_t			pos;		/* Where to start reading */
205e8e581a8SDavid Howells	loff_t			len;		/* How much we're asking for */
206196ee9cdSDavid Howells	loff_t			actual_len;	/* How much we're actually getting */
207f3ddee8dSDavid Howells	loff_t			file_size;	/* File size returned by server */
208c69bf479SDavid Howells	struct key		*key;		/* The key to use to reissue the read */
209c4508464SDavid Howells	struct afs_vnode	*vnode;		/* The file being read into. */
2105cbf0398SDavid Howells	struct netfs_read_subrequest *subreq;	/* Fscache helper read request this belongs to */
211f3ddee8dSDavid Howells	afs_dataversion_t	data_version;	/* Version number returned by server */
212f3ddee8dSDavid Howells	refcount_t		usage;
213c4508464SDavid Howells	unsigned int		call_debug_id;
214196ee9cdSDavid Howells	unsigned int		nr_pages;
215c4508464SDavid Howells	int			error;
216c4508464SDavid Howells	void (*done)(struct afs_read *);
217c4508464SDavid Howells	void (*cleanup)(struct afs_read *);
218c4508464SDavid Howells	struct iov_iter		*iter;		/* Iterator representing the buffer */
219c4508464SDavid Howells	struct iov_iter		def_iter;	/* Default iterator */
220196ee9cdSDavid Howells};
221196ee9cdSDavid Howells
22208e0e7c8SDavid Howells/*
22308e0e7c8SDavid Howells * AFS superblock private data
22408e0e7c8SDavid Howells * - there's one superblock per volume
22508e0e7c8SDavid Howells */
22608e0e7c8SDavid Howellsstruct afs_super_info {
2275b86d4ffSDavid Howells	struct net		*net_ns;	/* Network namespace */
22849566f6fSDavid Howells	struct afs_cell		*cell;		/* The cell in which the volume resides */
22908e0e7c8SDavid Howells	struct afs_volume	*volume;	/* volume record */
2306c6c1d63SDavid Howells	enum afs_flock_mode	flock_mode:8;	/* File locking emulation mode */
2314d673da1SDavid Howells	bool			dyn_root;	/* True if dynamic root */
23208e0e7c8SDavid Howells};
2331da177e4SLinus Torvalds
23408e0e7c8SDavid Howellsstatic inline struct afs_super_info *AFS_FS_S(struct super_block *sb)
23508e0e7c8SDavid Howells{
23608e0e7c8SDavid Howells	return sb->s_fs_info;
2371da177e4SLinus Torvalds}
2381da177e4SLinus Torvalds
23908e0e7c8SDavid Howellsextern struct file_system_type afs_fs_type;
24008e0e7c8SDavid Howells
2416f8880d8SDavid Howells/*
2426f8880d8SDavid Howells * Set of substitutes for @sys.
2436f8880d8SDavid Howells */
2446f8880d8SDavid Howellsstruct afs_sysnames {
2456f8880d8SDavid Howells#define AFS_NR_SYSNAME 16
2466f8880d8SDavid Howells	char			*subs[AFS_NR_SYSNAME];
2476f8880d8SDavid Howells	refcount_t		usage;
2486f8880d8SDavid Howells	unsigned short		nr;
2496f8880d8SDavid Howells	char			blank[1];
2506f8880d8SDavid Howells};
2516f8880d8SDavid Howells
252f044c884SDavid Howells/*
253f044c884SDavid Howells * AFS network namespace record.
254f044c884SDavid Howells */
255f044c884SDavid Howellsstruct afs_net {
2565b86d4ffSDavid Howells	struct net		*net;		/* Backpointer to the owning net namespace */
257f044c884SDavid Howells	struct afs_uuid		uuid;
258f044c884SDavid Howells	bool			live;		/* F if this namespace is being removed */
259f044c884SDavid Howells
260f044c884SDavid Howells	/* AF_RXRPC I/O stuff */
261f044c884SDavid Howells	struct socket		*socket;
262f044c884SDavid Howells	struct afs_call		*spare_incoming_call;
263f044c884SDavid Howells	struct work_struct	charge_preallocation_work;
264f044c884SDavid Howells	struct mutex		socket_mutex;
265f044c884SDavid Howells	atomic_t		nr_outstanding_calls;
266f044c884SDavid Howells	atomic_t		nr_superblocks;
267f044c884SDavid Howells
268f044c884SDavid Howells	/* Cell database */
269989782dcSDavid Howells	struct rb_root		cells;
27092e3cc91SDavid Howells	struct afs_cell		*ws_cell;
271989782dcSDavid Howells	struct work_struct	cells_manager;
272989782dcSDavid Howells	struct timer_list	cells_timer;
273989782dcSDavid Howells	atomic_t		cells_outstanding;
27492e3cc91SDavid Howells	struct rw_semaphore	cells_lock;
2758a070a96SDavid Howells	struct mutex		cells_alias_lock;
276f044c884SDavid Howells
2770da0b7fdSDavid Howells	struct mutex		proc_cells_lock;
2786b3944e4SDavid Howells	struct hlist_head	proc_cells;
279f044c884SDavid Howells
280d2ddc776SDavid Howells	/* Known servers.  Theoretically each fileserver can only be in one
281d2ddc776SDavid Howells	 * cell, but in practice, people create aliases and subsets and there's
282d2ddc776SDavid Howells	 * no easy way to distinguish them.
283d2ddc776SDavid Howells	 */
284f6cbb368SDavid Howells	seqlock_t		fs_lock;	/* For fs_servers, fs_probe_*, fs_proc */
285d2ddc776SDavid Howells	struct rb_root		fs_servers;	/* afs_server (by server UUID or address) */
286f6cbb368SDavid Howells	struct list_head	fs_probe_fast;	/* List of afs_server to probe at 30s intervals */
287f6cbb368SDavid Howells	struct list_head	fs_probe_slow;	/* List of afs_server to probe at 5m intervals */
288d2ddc776SDavid Howells	struct hlist_head	fs_proc;	/* procfs servers list */
289f044c884SDavid Howells
290d2ddc776SDavid Howells	struct hlist_head	fs_addresses4;	/* afs_server (by lowest IPv4 addr) */
291d2ddc776SDavid Howells	struct hlist_head	fs_addresses6;	/* afs_server (by lowest IPv6 addr) */
292d2ddc776SDavid Howells	seqlock_t		fs_addr_lock;	/* For fs_addresses[46] */
293f044c884SDavid Howells
294d2ddc776SDavid Howells	struct work_struct	fs_manager;