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