xref: /netbsd/sys/fs/efs/efs_dinode.h (revision 6550d01e)
1 /*	$NetBSD: efs_dinode.h,v 1.2 2007/06/30 15:56:16 rumble Exp $	*/
2 
3 /*
4  * Copyright (c) 2006 Stephen M. Rumble <rumble@ephemeral.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*
20  * EFS on-disk inode format.
21  *
22  * See IRIX inode(4)
23  */
24 
25 #ifndef _FS_EFS_EFS_DINODE_H_
26 #define _FS_EFS_EFS_DINODE_H_
27 
28 /*
29  * Historical locations are always good.
30  */
31 #define EFS_ROOTINO	((ino_t)2)
32 
33 /*
34  * EFS on-disk inode structure (128 bytes)
35  *
36  * [0] - NetBSD native uid_t is uint32_t.
37  * [1] - NetBSD native gid_t is uint32_t.
38  * [2] - NetBSD native off_t is int64_t.
39  * [3] - See notes for di_u below for meanings of di_numextents.
40  * [4] - Always 0 with EFS. Apparently it could take on other values when
41  *	 used in conjunction with AFS.
42  */
43 
44 #define EFS_DIRECTEXTENTS 12
45 struct efs_dinode {
46 	uint16_t	di_mode;	/* 0:  file type and permissions */
47 	int16_t		di_nlink;	/* 2:  link count (minimum 2) */
48 	uint16_t	di_uid;		/* 4:  user ID [0] */
49 	uint16_t	di_gid;		/* 6:  group ID [1] */
50 	int32_t		di_size;	/* 8:  file size (in bytes) [2] */
51 	uint32_t	di_atime;	/* 12: file access time */
52 	uint32_t	di_mtime;	/* 16: file modification time */
53 	uint32_t	di_ctime;	/* 20: inode modification time */
54 	int32_t		di_gen;		/* 24: inode generation number */
55 	int16_t		di_numextents;	/* 28: number of extents in file [3] */
56 	uint8_t		di_version;	/* 30: inode version [4] */
57 	uint8_t		di_spare;	/* 31: unused */
58 
59 	union {
60 		/*
61 		 * If di_numextents <= EFS_DIRECTEXTENTS, _di_extents contains
62 		 * direct extent descriptors.
63 		 *
64 		 * else (di_numextents > EFS_DIRECTEXTENTS), _di_extents
65 		 * contains indirect extent descriptors.
66 		 *
67 		 * If indirect extents are being used, extents[0].ex_offset
68 		 * contains the number of indirect extents, i.e. the valid
69 		 * offsets in 'extents' are:
70 		 *     extents[0 ... (extents[0].ex_offset - 1)]
71 		 * It's not presently known if the ex_offset fields in
72 		 * extents[1 ... EFS_DIRECTEXTENTS] have any meaning.
73 		 */
74 		struct efs_dextent extents[EFS_DIRECTEXTENTS];
75 
76 		/*
77 		 * If di_numextents == 0 and di_mode indicates a symlink, the
78 		 * symlink path is inlined into _di_symlink. Otherwise, the
79 		 * symlink exists in extents.
80 		 *
81 		 * Note that the symlink is stored without nul-termination,
82 		 * and di_size reflects this length.
83 		 */
84 		char symlink[sizeof(struct efs_dextent) * EFS_DIRECTEXTENTS];
85 
86 		/*
87 		 * If di_numextents == 0 and di_mode indicates a character or
88 		 * block special file, the device tag is contained in _di_dev.
89 		 *
90 		 * Note that IRIX moved from 16bit to 32bit dev_t's at some
91 		 * point and a new field was added. It appears that when 32bit
92 		 * dev_t's are used, di_odev is set to 0xffff.
93 		 */
94 		struct {
95 			uint16_t dev_old;
96 			uint32_t dev_new;
97 		} __packed dev;
98 	} di_u;
99 } __packed;
100 
101 #define di_extents	di_u.extents
102 #define di_symlink	di_u.symlink
103 #define di_odev		di_u.dev.dev_old
104 #define di_ndev		di_u.dev.dev_new
105 
106 #define EFS_DINODE_SIZE		sizeof(struct efs_dinode)
107 #define EFS_DINODES_PER_BB	(EFS_BB_SIZE / EFS_DINODE_SIZE)
108 
109 #define EFS_DINODE_ODEV_INVALID	(0xffff)
110 #define EFS_DINODE_ODEV_MAJ(_x)	(((_x) >>  8) & 0x7f)
111 #define EFS_DINODE_ODEV_MIN(_x)	(((_x) >>  0) & 0xff)
112 #define EFS_DINODE_NDEV_MAJ(_x)	(((_x) >> 18) & 0x1ff)
113 #define EFS_DINODE_NDEV_MIN(_x)	(((_x) >>  0) & 0x3ffff)
114 
115 /* EFS file permissions. */
116 #define EFS_IEXEC	0000100		/* executable */
117 #define EFS_IWRITE	0000200		/* writable */
118 #define EFS_IREAD	0000400		/* readable */
119 #define EFS_ISVTX	0001000		/* sticky bit */
120 #define EFS_ISGID	0002000		/* setgid */
121 #define EFS_ISUID	0004000		/* setuid */
122 
123 /* EFS file types. */
124 #define EFS_IFMT	0170000		/* file type mask */
125 #define EFS_IFIFO	0010000		/* named pipe */
126 #define EFS_IFCHR	0020000		/* character device */
127 #define EFS_IFDIR	0040000		/* directory */
128 #define EFS_IFBLK	0060000		/* block device */
129 #define EFS_IFREG	0100000		/* regular file */
130 #define EFS_IFLNK	0120000		/* symlink */
131 #define EFS_IFSOCK	0140000		/* UNIX domain socket */
132 
133 #endif /* !_FS_EFS_EFS_DINODE_H_ */
134