1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /* AFS fileserver XDR types
3  *
4  * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells (dhowells@redhat.com)
6  */
7 
8 #ifndef XDR_FS_H
9 #define XDR_FS_H
10 
11 struct afs_xdr_AFSFetchStatus {
12 	__be32	if_version;
13 #define AFS_FSTATUS_VERSION	1
14 	__be32	type;
15 	__be32	nlink;
16 	__be32	size_lo;
17 	__be32	data_version_lo;
18 	__be32	author;
19 	__be32	owner;
20 	__be32	caller_access;
21 	__be32	anon_access;
22 	__be32	mode;
23 	__be32	parent_vnode;
24 	__be32	parent_unique;
25 	__be32	seg_size;
26 	__be32	mtime_client;
27 	__be32	mtime_server;
28 	__be32	group;
29 	__be32	sync_counter;
30 	__be32	data_version_hi;
31 	__be32	lock_count;
32 	__be32	size_hi;
33 	__be32	abort_code;
34 } __packed;
35 
36 #define AFS_DIR_HASHTBL_SIZE	128
37 #define AFS_DIR_DIRENT_SIZE	32
38 #define AFS_DIR_SLOTS_PER_BLOCK	64
39 #define AFS_DIR_BLOCK_SIZE	2048
40 #define AFS_DIR_BLOCKS_PER_PAGE	(PAGE_SIZE / AFS_DIR_BLOCK_SIZE)
41 #define AFS_DIR_MAX_SLOTS	65536
42 #define AFS_DIR_BLOCKS_WITH_CTR	128
43 #define AFS_DIR_MAX_BLOCKS	1023
44 #define AFS_DIR_RESV_BLOCKS	1
45 #define AFS_DIR_RESV_BLOCKS0	13
46 
47 /*
48  * Directory entry structure.
49  */
50 union afs_xdr_dirent {
51 	struct {
52 		u8		valid;
53 		u8		unused[1];
54 		__be16		hash_next;
55 		__be32		vnode;
56 		__be32		unique;
57 		u8		name[];
58 		/* When determining the number of dirent slots needed to
59 		 * represent a directory entry, name should be assumed to be 16
60 		 * bytes, due to a now-standardised (mis)calculation, but it is
61 		 * in fact 20 bytes in size.  afs_dir_calc_slots() should be
62 		 * used for this.
63 		 *
64 		 * For names longer than (16 or) 20 bytes, extra slots should
65 		 * be annexed to this one using the extended_name format.
66 		 */
67 	} u;
68 	u8			extended_name[32];
69 } __packed;
70 
71 /*
72  * Directory block header (one at the beginning of every 2048-byte block).
73  */
74 struct afs_xdr_dir_hdr {
75 	__be16		npages;
76 	__be16		magic;
77 #define AFS_DIR_MAGIC htons(1234)
78 	u8		reserved;
79 	u8		bitmap[8];
80 	u8		pad[19];
81 } __packed;
82 
83 /*
84  * Directory block layout
85  */
86 union afs_xdr_dir_block {
87 	struct afs_xdr_dir_hdr		hdr;
88 
89 	struct {
90 		struct afs_xdr_dir_hdr	hdr;
91 		u8			alloc_ctrs[AFS_DIR_MAX_BLOCKS];
92 		__be16			hashtable[AFS_DIR_HASHTBL_SIZE];
93 	} meta;
94 
95 	union afs_xdr_dirent	dirents[AFS_DIR_SLOTS_PER_BLOCK];
96 } __packed;
97 
98 /*
99  * Directory layout on a linux VM page.
100  */
101 struct afs_xdr_dir_page {
102 	union afs_xdr_dir_block	blocks[AFS_DIR_BLOCKS_PER_PAGE];
103 };
104 
105 /*
106  * Calculate the number of dirent slots required for any given name length.
107  * The calculation is made assuming the part of the name in the first slot is
108  * 16 bytes, rather than 20, but this miscalculation is now standardised.
109  */
afs_dir_calc_slots(size_t name_len)110 static inline unsigned int afs_dir_calc_slots(size_t name_len)
111 {
112 	name_len++; /* NUL-terminated */
113 	return 1 + ((name_len + 15) / AFS_DIR_DIRENT_SIZE);
114 }
115 
116 #endif /* XDR_FS_H */
117