Lecture 18

Superblock and Inode Operations
super_operations
Ext2 defines the following operations in the super_operations object:
read_inode:     ext2_read_inode,
write_inode:    ext2_write_inode,
put_inode:      ext2_put_inode,
delete_inode:   ext2_delete_inode,
put_super:      ext2_put_super,
write_super:    ext2_write_super,
statfs:         ext2_statfs,
remount_fs:     ext2_remount,
Ext2 leaves the following super_operations undefined: The Coda file system (a network file system for mobile devices) provides only the following supe_operations:
read_inode:     coda_read_inode,
clear_inode:    coda_clear_inode,
put_super:      coda_put_super,
statfs:         coda_statfs,
inode_operations
Ext3 provides three different sets of inode_operations: In file.c:

struct inode_operations ext3_file_inode_operations = {
        truncate:       ext3_truncate,          /* BKL held */
        setattr:        ext3_setattr,           /* BKL held */
};

In namei.c (two different ways):

/*
 * directories can handle most operations...
 */
struct inode_operations ext3_dir_inode_operations = {
        create:         ext3_create,            /* BKL held */
        lookup:         ext3_lookup,            /* BKL held */
        link:           ext3_link,              /* BKL held */
        unlink:         ext3_unlink,            /* BKL held */
        symlink:        ext3_symlink,           /* BKL held */
        mkdir:          ext3_mkdir,             /* BKL held */
        rmdir:          ext3_rmdir,             /* BKL held */
        mknod:          ext3_mknod,             /* BKL held */
        rename:         ext3_rename,            /* BKL held */
};


struct inode_operations page_symlink_inode_operations = {
        readlink:       page_readlink,
        follow_link:    page_follow_link,
};

In symlink.c:
struct inode_operations ext3_fast_symlink_inode_operations = {
        readlink:       ext3_readlink,          /* BKL not held.  Don't need */
        follow_link:    ext3_follow_link,       /* BKL not held.  Don't need */
};
And finally in bad_inode.c:
struct inode_operations bad_inode_ops =
{
        create:         EIO_ERROR,
        lookup:         EIO_ERROR,
        link:           EIO_ERROR,
        unlink:         EIO_ERROR,
        symlink:        EIO_ERROR,
        mkdir:          EIO_ERROR,
        rmdir:          EIO_ERROR,
        mknod:          EIO_ERROR,
        rename:         EIO_ERROR,
        readlink:       EIO_ERROR,
        follow_link:    bad_follow_link,
        truncate:       EIO_ERROR,
        permission:     EIO_ERROR,
        revalidate:     EIO_ERROR,
};

static int bad_follow_link(struct dentry *dent, struct nameidata *nd)
{
        return vfs_follow_link(nd, ERR_PTR(-EIO));
}

static int return_EIO(void)
{
        return -EIO;
}

static inline void *ERR_PTR(long error)
{
        return (void *) error;
}

#define EIO_ERROR ((void *) (return_EIO))
The following initialization code appears in ext3_read_inode in inode.c:
if (inode->i_ino == EXT3_ACL_IDX_INO ||
        inode->i_ino == EXT3_ACL_DATA_INO)
        /* Nothing to do */ ;
else if (S_ISREG(inode->i_mode)) {
        inode->i_op = &ext3_file_inode_operations;
        inode->i_fop = &ext3_file_operations;
        inode->i_mapping->a_ops = &ext3_aops;
} else if (S_ISDIR(inode->i_mode)) {
        inode->i_op = &ext3_dir_inode_operations;
        inode->i_fop = &ext3_dir_operations;
} else if (S_ISLNK(inode->i_mode)) {
        if (!inode->i_blocks)
                inode->i_op = &ext3_fast_symlink_inode_operations;
        else {
                inode->i_op = &page_symlink_inode_operations;
                inode->i_mapping->a_ops = &ext3_aops;
        }
} else
        init_special_inode(inode, inode->i_mode,
                           le32_to_cpu(iloc.raw_inode->i_block[0]));