xref: /linux/fs/afs/xdr_fs.h (revision f8bade6c9a6213c2c5ba6e5bf32415ecab6e41e5)
1b4d0d230SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2dd9fbcb8SDavid Howells /* AFS fileserver XDR types
3dd9fbcb8SDavid Howells  *
4dd9fbcb8SDavid Howells  * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
5dd9fbcb8SDavid Howells  * Written by David Howells (dhowells@redhat.com)
6dd9fbcb8SDavid Howells  */
7dd9fbcb8SDavid Howells 
8dd9fbcb8SDavid Howells #ifndef XDR_FS_H
9dd9fbcb8SDavid Howells #define XDR_FS_H
10dd9fbcb8SDavid Howells 
11dd9fbcb8SDavid Howells struct afs_xdr_AFSFetchStatus {
12dd9fbcb8SDavid Howells 	__be32	if_version;
13dd9fbcb8SDavid Howells #define AFS_FSTATUS_VERSION	1
14dd9fbcb8SDavid Howells 	__be32	type;
15dd9fbcb8SDavid Howells 	__be32	nlink;
16dd9fbcb8SDavid Howells 	__be32	size_lo;
17dd9fbcb8SDavid Howells 	__be32	data_version_lo;
18dd9fbcb8SDavid Howells 	__be32	author;
19dd9fbcb8SDavid Howells 	__be32	owner;
20dd9fbcb8SDavid Howells 	__be32	caller_access;
21dd9fbcb8SDavid Howells 	__be32	anon_access;
22dd9fbcb8SDavid Howells 	__be32	mode;
23dd9fbcb8SDavid Howells 	__be32	parent_vnode;
24dd9fbcb8SDavid Howells 	__be32	parent_unique;
25dd9fbcb8SDavid Howells 	__be32	seg_size;
26dd9fbcb8SDavid Howells 	__be32	mtime_client;
27dd9fbcb8SDavid Howells 	__be32	mtime_server;
28dd9fbcb8SDavid Howells 	__be32	group;
29dd9fbcb8SDavid Howells 	__be32	sync_counter;
30dd9fbcb8SDavid Howells 	__be32	data_version_hi;
31dd9fbcb8SDavid Howells 	__be32	lock_count;
32dd9fbcb8SDavid Howells 	__be32	size_hi;
33dd9fbcb8SDavid Howells 	__be32	abort_code;
34dd9fbcb8SDavid Howells } __packed;
35dd9fbcb8SDavid Howells 
364ea219a8SDavid Howells #define AFS_DIR_HASHTBL_SIZE	128
374ea219a8SDavid Howells #define AFS_DIR_DIRENT_SIZE	32
384ea219a8SDavid Howells #define AFS_DIR_SLOTS_PER_BLOCK	64
394ea219a8SDavid Howells #define AFS_DIR_BLOCK_SIZE	2048
404ea219a8SDavid Howells #define AFS_DIR_BLOCKS_PER_PAGE	(PAGE_SIZE / AFS_DIR_BLOCK_SIZE)
414ea219a8SDavid Howells #define AFS_DIR_MAX_SLOTS	65536
424ea219a8SDavid Howells #define AFS_DIR_BLOCKS_WITH_CTR	128
434ea219a8SDavid Howells #define AFS_DIR_MAX_BLOCKS	1023
444ea219a8SDavid Howells #define AFS_DIR_RESV_BLOCKS	1
454ea219a8SDavid Howells #define AFS_DIR_RESV_BLOCKS0	13
464ea219a8SDavid Howells 
474ea219a8SDavid Howells /*
484ea219a8SDavid Howells  * Directory entry structure.
494ea219a8SDavid Howells  */
5000317636SDavid Howells union afs_xdr_dirent {
514ea219a8SDavid Howells 	struct {
5200317636SDavid Howells 		u8		valid;
5300317636SDavid Howells 		u8		unused[1];
544ea219a8SDavid Howells 		__be16		hash_next;
554ea219a8SDavid Howells 		__be32		vnode;
564ea219a8SDavid Howells 		__be32		unique;
5726982a89SDavid Howells 		u8		name[];
5826982a89SDavid Howells 		/* When determining the number of dirent slots needed to
5926982a89SDavid Howells 		 * represent a directory entry, name should be assumed to be 16
6026982a89SDavid Howells 		 * bytes, due to a now-standardised (mis)calculation, but it is
61*366911cdSDavid Howells 		 * in fact 20 bytes in size.  afs_dir_calc_slots() should be
62*366911cdSDavid Howells 		 * used for this.
6326982a89SDavid Howells 		 *
6426982a89SDavid Howells 		 * For names longer than (16 or) 20 bytes, extra slots should
6526982a89SDavid Howells 		 * be annexed to this one using the extended_name format.
6626982a89SDavid Howells 		 */
674ea219a8SDavid Howells 	} u;
6800317636SDavid Howells 	u8			extended_name[32];
6900317636SDavid Howells } __packed;
704ea219a8SDavid Howells 
714ea219a8SDavid Howells /*
7200317636SDavid Howells  * Directory block header (one at the beginning of every 2048-byte block).
734ea219a8SDavid Howells  */
7400317636SDavid Howells struct afs_xdr_dir_hdr {
754ea219a8SDavid Howells 	__be16		npages;
764ea219a8SDavid Howells 	__be16		magic;
774ea219a8SDavid Howells #define AFS_DIR_MAGIC htons(1234)
7800317636SDavid Howells 	u8		reserved;
7900317636SDavid Howells 	u8		bitmap[8];
8000317636SDavid Howells 	u8		pad[19];
8100317636SDavid Howells } __packed;
824ea219a8SDavid Howells 
834ea219a8SDavid Howells /*
844ea219a8SDavid Howells  * Directory block layout
854ea219a8SDavid Howells  */
8600317636SDavid Howells union afs_xdr_dir_block {
8700317636SDavid Howells 	struct afs_xdr_dir_hdr		hdr;
884ea219a8SDavid Howells 
894ea219a8SDavid Howells 	struct {
9000317636SDavid Howells 		struct afs_xdr_dir_hdr	hdr;
9100317636SDavid Howells 		u8			alloc_ctrs[AFS_DIR_MAX_BLOCKS];
924ea219a8SDavid Howells 		__be16			hashtable[AFS_DIR_HASHTBL_SIZE];
9300317636SDavid Howells 	} meta;
944ea219a8SDavid Howells 
9500317636SDavid Howells 	union afs_xdr_dirent	dirents[AFS_DIR_SLOTS_PER_BLOCK];
9600317636SDavid Howells } __packed;
974ea219a8SDavid Howells 
984ea219a8SDavid Howells /*
994ea219a8SDavid Howells  * Directory layout on a linux VM page.
1004ea219a8SDavid Howells  */
10100317636SDavid Howells struct afs_xdr_dir_page {
10200317636SDavid Howells 	union afs_xdr_dir_block	blocks[AFS_DIR_BLOCKS_PER_PAGE];
1034ea219a8SDavid Howells };
1044ea219a8SDavid Howells 
105*366911cdSDavid Howells /*
106*366911cdSDavid Howells  * Calculate the number of dirent slots required for any given name length.
107*366911cdSDavid Howells  * The calculation is made assuming the part of the name in the first slot is
108*366911cdSDavid Howells  * 16 bytes, rather than 20, but this miscalculation is now standardised.
109*366911cdSDavid Howells  */
afs_dir_calc_slots(size_t name_len)110*366911cdSDavid Howells static inline unsigned int afs_dir_calc_slots(size_t name_len)
111*366911cdSDavid Howells {
112*366911cdSDavid Howells 	name_len++; /* NUL-terminated */
113*366911cdSDavid Howells 	return 1 + ((name_len + 15) / AFS_DIR_DIRENT_SIZE);
114*366911cdSDavid Howells }
115*366911cdSDavid Howells 
116dd9fbcb8SDavid Howells #endif /* XDR_FS_H */
117