structinode { structhlist_nodei_hash;/* hash list */ structlist_headi_list;/* list of inodes */ structlist_headi_dentry;/* list of dentries */ unsignedlong i_ino; /* inode number */ atomic_t i_count; /* reference counter */ umode_t i_mode; /* access permissions */ unsignedint i_nlink; /* number of hard links */ uid_t i_uid; /* user id of owner */ gid_t i_gid; /* group id of owner */ kdev_t i_rdev; /* real device node */ loff_t i_size; /* file size in bytes */ structtimespeci_atime;/* last access time */ structtimespeci_mtime;/* last modify time */ structtimespeci_ctime;/* last change time */ unsignedint i_blkbits; /* block size in bits */ unsignedlong i_blksize; /* block size in bytes */ unsignedlong i_version; /* version number */ unsignedlong i_blocks; /* file size in blocks */ unsignedshort i_bytes; /* bytes consumed */ spinlock_t i_lock; /* spinlock */ structrw_semaphorei_alloc_sem;/* nests inside of i_sem */ structsemaphorei_sem;/* inode semaphore */ structinode_operations *i_op;/* inode ops table */ structsuper_block *i_sb;/* associated superblock */ structfile_lock *i_flock;/* file lock list */ structaddress_space *i_mapping;/* associated mapping */ structaddress_spacei_data;/* mapping for device */ structdquot *i_dquot[MAXQUOTAS];/* disk quotas for inode */ unsignedlong i_state; /* state flags */ unsignedlong dirtied_when; /* first dirtying time */ unsignedint i_flags; /* filesystem flags */ atomic_t i_writecount; /* count of writers */ // ... };
4.2 Inode Operations
structinode_operations { /* open(), creat(): create a new inode associated with the dentry `dentry` in a parent inode directory `dir` with given mode */ intcreate(struct inode *dir, struct dentry *dentry, int mode);
/* search an inode in a parent inode directory `dir`. The name to look for is in the dentry `dentry`. If target inode does not exist, a NULL inode should be inserted into the dentry(called a negative dentry) */ struct dentry* lookup(struct inode *dir, struct dentry *dentry);
/* link(): create a hard link of the file `old` in the directory `dir` with the new filename `dentry` */ intlink(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry); /* unlink(): remove the inode specified by the dentry `dentry` from the directory `dir` */ intunlink(struct inode *dir, struct dentry *dentry); /* symlink(): create a symbolic link named `symname` of the file `dentry` in the directory `dir` */ intsymlink(struct inode *dir, struct dentry *dentry, constchar *symname);
/* mkdir(): create a new directory with the given initial mode */ intmkdir(struct inode *dir, struct dentry *dentry, int mode); /* rmdir(): remove the directory referenced by `dentry` from the directory `dir` */ intrmdir(struct inode *dir, struct dentry *dentry);
/* mknod(): create a special file (device, pipe or socket). The file is referenced by the device ID `rdev` and dentry `dentry` in the directory `dir`. Initial permissions are given via `mode`. */ intmknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev);
/* rename(): move the file specified by `old_dentry` from `old_dir` directory to `new_dir` directory. Filename specified by `new_dentry` */ intrename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry); /* copy at most `buflen` bytes of the full path associated with the symbolic link specified by `dentry` into the specified buffer */ intreadlink(struct dentry *dentry, char *buffer, int buflen);
/* translate a symbolic link to the inode to which it points. The link pointed at by `dentry` is translated and the result is stored in the nameidata structure pointed at by `nd` */ intfollow_link(struct dentry *dentry, struct nameidata *nd); /* clean up after a call to follow_link() */ intput_link(struct dentry *dentry, struct nameidata *nd);
/* modify the size of the given file referenced by inode `inode`. The new size of file should be set in `i_size` field */ voidtruncate(struct inode *inode);
/* check whether the specified access mode `mask` is allowed for the file referenced by inode `inode` */ intpermission(struct inode *inode, int mask);
/* create and initialize a new inode object under the given superblock */ struct inode* alloc_inode(struct super_block *sb)
/* deallocates the given inode pointed to by `inode` */ voiddestroy_inode(struct inode *inode)
/* reads the inode specified by inode->i_ino from disk and fills in the rest of the inode structure */ voidread_inode(struct inode *inode)
/* invoked by VFS when an inode is dirtied(modified) */ voiddirty_inode(struct inode *inode)
/* write the given inode to disk, `wait` parameter specifies whether the operation should be synchronous */ voidwrite_inode(struct inode *inode, int wait)
/* release the given inode */ voidput_inode(struct inode *inode)
/* invoked by VFS when the last reference to the inode is dropped */ voiddrop_inode(struct inode *inode)
/* delete the given inode from the disk */ voiddelete_inode(struct inode *inode)
/* invoked by VFS when free the superblock(unmount) */ voidput_super(struct super_block *sb)
/* update the on-disk superblock with the specified superblock */ voidwrite_super(struct super_block *sb)
/* synchronize filesystem metadata with the on-disk filesystem */ intsync_fs(struct super_block *sb, int wait)