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 | */ |
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 | |