xref: /minix3/minix/lib/libsffs/inode.h (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc #ifndef _SFFS_INODE_H
2*433d6423SLionel Sambuc #define _SFFS_INODE_H
3*433d6423SLionel Sambuc 
4*433d6423SLionel Sambuc /* We cannot use inode number 0, so to be able to use bitmasks to combine
5*433d6423SLionel Sambuc  * inode and generation numbers, we have to use one fewer than the maximum of
6*433d6423SLionel Sambuc  * inodes possible by using NUM_INODE_BITS bits.
7*433d6423SLionel Sambuc  */
8*433d6423SLionel Sambuc #define NUM_INODES	((1 << NUM_INODE_BITS) - 1)
9*433d6423SLionel Sambuc 
10*433d6423SLionel Sambuc /* The main portion of the inode array forms a fully linked tree, providing a
11*433d6423SLionel Sambuc  * cached partial view of what the server believes is on the host system. Each
12*433d6423SLionel Sambuc  * inode contains only a pointer to its parent and its path component name, so
13*433d6423SLionel Sambuc  * a path for an inode is constructed by walking up to the root. Inodes that
14*433d6423SLionel Sambuc  * are in use as directory for a child node must not be recycled; in this case,
15*433d6423SLionel Sambuc  * the i_child list is not empty. Naturally, inodes for which VFS holds a
16*433d6423SLionel Sambuc  * reference must also not be recycled; the i_ref count takes care of that.
17*433d6423SLionel Sambuc  *
18*433d6423SLionel Sambuc  * Multiple hard links to a single file do not exist; that is why an inode is
19*433d6423SLionel Sambuc  * also a directory entry (when in IN USE or CACHED state). Notifications about
20*433d6423SLionel Sambuc  * modifications on the host system are not part of the protocol, so sometimes
21*433d6423SLionel Sambuc  * the server may discover that some files do not exist anymore. In that case,
22*433d6423SLionel Sambuc  * they are marked as DELETED in the inode table. Such files may still be used
23*433d6423SLionel Sambuc  * because of open file handles, but cannot be referenced by path anymore. The
24*433d6423SLionel Sambuc  * underlying protocol may not support truncation of open files anyway. Since
25*433d6423SLionel Sambuc  * we currently cannot guarantee that a file is actually opened before it is
26*433d6423SLionel Sambuc  * deleted (as this would consistute opening every file being looked up), we
27*433d6423SLionel Sambuc  * effectively do not properly support open deleted files at all anyway.
28*433d6423SLionel Sambuc  *
29*433d6423SLionel Sambuc  * An inode is REFERENCED iff it has a reference count > 0 *or* has children.
30*433d6423SLionel Sambuc  * An inode is LINKED IN iff it has a parent.
31*433d6423SLionel Sambuc  *
32*433d6423SLionel Sambuc  * An inode is IN USE iff it is REFERENCED and LINKED IN.
33*433d6423SLionel Sambuc  * An inode is CACHED iff it is NOT REFERENCED and LINKED IN.
34*433d6423SLionel Sambuc  * An inode is DELETED iff it is REFERENCED and NOT LINKED IN.
35*433d6423SLionel Sambuc  * An inode is FREE iff it is NOT REFERENCED and NOT LINKED IN.
36*433d6423SLionel Sambuc  *
37*433d6423SLionel Sambuc  * An inode may have an open file handle if it is IN USE or DELETED.
38*433d6423SLionel Sambuc  * An inode may have children if it is IN USE (and is a directory).
39*433d6423SLionel Sambuc  * An inode is in the names hashtable iff it is IN USE or CACHED.
40*433d6423SLionel Sambuc  * An inode is on the free list iff it is CACHED or FREE.
41*433d6423SLionel Sambuc  *
42*433d6423SLionel Sambuc  * - An IN USE inode becomes DELETED when it is either deleted explicitly, or
43*433d6423SLionel Sambuc  *   when it has been determined to have become unreachable by path name on the
44*433d6423SLionel Sambuc  *   host system (the verify_* functions take care of this).
45*433d6423SLionel Sambuc  * - An IN USE inode may become CACHED when there are no VFS references to it
46*433d6423SLionel Sambuc  *   anymore (i_ref == 0), and it is not a directory with children.
47*433d6423SLionel Sambuc  * - A DELETED inode cannot have children, but may become FREE when there are
48*433d6423SLionel Sambuc  *   also no VFS references to it anymore.
49*433d6423SLionel Sambuc  * - A CACHED inode may become IN USE when either i_ref or i_link is increased
50*433d6423SLionel Sambuc  *   from zero. Practically, it will always be i_ref that gets increased, since
51*433d6423SLionel Sambuc  *   i_link cannot be increased by VFS without having a reference to the inode.
52*433d6423SLionel Sambuc  * - A CACHED or FREE inode may be reused for other purposes at any time.
53*433d6423SLionel Sambuc  */
54*433d6423SLionel Sambuc 
55*433d6423SLionel Sambuc struct inode {
56*433d6423SLionel Sambuc   struct inode *i_parent;		/* parent inode pointer */
57*433d6423SLionel Sambuc   LIST_HEAD(child_head, inode) i_child;	/* child inode anchor */
58*433d6423SLionel Sambuc   LIST_ENTRY(inode) i_next;		/* sibling inode chain entry */
59*433d6423SLionel Sambuc   LIST_ENTRY(inode) i_hash;		/* hashtable chain entry */
60*433d6423SLionel Sambuc   unsigned short i_num;			/* inode number for quick reference */
61*433d6423SLionel Sambuc   unsigned short i_gen;			/* inode generation number */
62*433d6423SLionel Sambuc   unsigned short i_ref;			/* VFS reference count */
63*433d6423SLionel Sambuc   unsigned short i_flags;		/* any combination of I_* flags */
64*433d6423SLionel Sambuc   union {
65*433d6423SLionel Sambuc 	TAILQ_ENTRY(inode) i_free;	/* free list chain entry */
66*433d6423SLionel Sambuc 	sffs_file_t i_file;		/* handle to open file */
67*433d6423SLionel Sambuc 	sffs_dir_t i_dir;		/* handle to open directory */
68*433d6423SLionel Sambuc   };
69*433d6423SLionel Sambuc   char i_name[NAME_MAX+1];		/* entry name in parent directory */
70*433d6423SLionel Sambuc };
71*433d6423SLionel Sambuc 
72*433d6423SLionel Sambuc #define I_DIR		0x01		/* this inode represents a directory */
73*433d6423SLionel Sambuc #define I_HANDLE	0x02		/* this inode has an open handle */
74*433d6423SLionel Sambuc 
75*433d6423SLionel Sambuc /* warning: the following line is not a proper macro */
76*433d6423SLionel Sambuc #define INODE_NR(i)	(((i)->i_gen << NUM_INODE_BITS) | (i)->i_num)
77*433d6423SLionel Sambuc #define INODE_INDEX(n)	(((n) & ((1 << NUM_INODE_BITS) - 1)) - 1)
78*433d6423SLionel Sambuc #define INODE_GEN(n)	(((n) >> NUM_INODE_BITS) & 0xffff)
79*433d6423SLionel Sambuc 
80*433d6423SLionel Sambuc #define ROOT_INODE_NR	1
81*433d6423SLionel Sambuc 
82*433d6423SLionel Sambuc #define IS_DIR(i)	((i)->i_flags & I_DIR)
83*433d6423SLionel Sambuc #define IS_ROOT(i)	((i)->i_num == ROOT_INODE_NR)
84*433d6423SLionel Sambuc #define HAS_CHILDREN(i)	(!LIST_EMPTY(&(i)->i_child))
85*433d6423SLionel Sambuc 
86*433d6423SLionel Sambuc #define MODE_TO_DIRFLAG(m)	(S_ISDIR(m) ? I_DIR : 0)
87*433d6423SLionel Sambuc 
88*433d6423SLionel Sambuc #endif /* _SFFS_INODE_H */
89