struct superblock

VFS defines a generic layout for the superblock through this structure. Each filesystem would need to instantiate an object of this structure to fill in its superblock details during mount. In other words, this structure abstracts the filesystem-specific superblock from the rest of the kernel, and helps VFS track all mounted filesystems through a list of struct super_block. Pseudo filesystems, which do not have persistent superblock structure, will dynamically generate superblocks. The superblock structure (struct super_block) is defined in <linux/fs.h>:

struct super_block {
struct list_head s_list; /* Keep this first */
dev_t s_dev; /* search index; _not_ kdev_t */
unsigned char s_blocksize_bits;
unsigned long s_blocksize;
loff_t s_maxbytes; /* Max file size */
struct file_system_type *s_type;
const struct super_operations *s_op;
const struct dquot_operations *dq_op;
const struct quotactl_ops *s_qcop;
const struct export_operations *s_export_op;
unsigned long s_flags;
unsigned long s_iflags; /* internal SB_I_* flags */
unsigned long s_magic;
struct dentry *s_root;
struct rw_semaphore s_umount;
int s_count;
atomic_t s_active;
#ifdef CONFIG_SECURITY
void *s_security;
#endif
const struct xattr_handler **s_xattr;
const struct fscrypt_operations *s_cop;
struct hlist_bl_head s_anon;
struct list_head s_mounts;/*list of mounts;_not_for fs use*/
struct block_device *s_bdev;
struct backing_dev_info *s_bdi;
struct mtd_info *s_mtd;
struct hlist_node s_instances;
unsigned int s_quota_types; /*Bitmask of supported quota types */
struct quota_info s_dquot; /* Diskquota specific options */
struct sb_writers s_writers;
char s_id[32]; /* Informational name */
u8 s_uuid[16]; /* UUID */
void *s_fs_info; /* Filesystem private info */
unsigned int s_max_links;
fmode_t s_mode;

/* Granularity of c/m/atime in ns.
Cannot be worse than a second */
u32 s_time_gran;


struct mutex s_vfs_rename_mutex; /* Kludge */

/*
* Filesystem subtype. If non-empty the filesystem type field
* in /proc/mounts will be "type.subtype"
*/
char *s_subtype;

/*
* Saved mount options for lazy filesystems using
* generic_show_options()
*/
char __rcu *s_options;
const struct dentry_operations *s_d_op; /*default op for dentries*/
/*
* Saved pool identifier for cleancache (-1 means none)
*/
int cleancache_poolid;

struct shrinker s_shrink; /* per-sb shrinker handle */

/* Number of inodes with nlink == 0 but still referenced */
atomic_long_t s_remove_count;

/* Being remounted read-only */
int s_readonly_remount;

/* AIO completions deferred from interrupt context */
struct workqueue_struct *s_dio_done_wq;
struct hlist_head s_pins;

/*
* Owning user namespace and default context in which to
* interpret filesystem uids, gids, quotas, device nodes,
* xattrs and security labels.
*/
struct user_namespace *s_user_ns;


struct list_lru s_dentry_lru ____cacheline_aligned_in_smp;
struct list_lru s_inode_lru ____cacheline_aligned_in_smp;
struct rcu_head rcu;
struct work_struct destroy_work;

struct mutex s_sync_lock; /* sync serialisation lock */

/*
* Indicates how deep in a filesystem stack this SB is
*/
int s_stack_depth;

/* s_inode_list_lock protects s_inodes */
spinlock_t s_inode_list_lock ____cacheline_aligned_in_smp;
struct list_head s_inodes; /* all inodes */

spinlock_t s_inode_wblist_lock;
struct list_head s_inodes_wb; /* writeback inodes */
};

The superblock structure contains other structures which define and extend the information and functionalities of the superblock. Following are some of the elements of super_block:

  • s_list is of type struct list_head and contains pointers to the list of mounted superblocks
  • s_dev is the device identifier
  • s_maxbytes contains the maximum file size
  • s_type is a pointer of type struct file_system_type, which describes the filesystem type
  • s_op is a pointer of type struct super_operations, containing operations on the superblock
  • s_export_op is of type struct export_operations and helps the filesystem be exportable for remote systems to access, using network filesystems
  • s_root is a pointer of type struct dentry and points to the dentry object of the filesystem's root directory

Each enumerated superblock instance contains a pointer to an abstract structure of function pointers that define the interface for superblock operations. Filesystems will need to implement their superblock operations and assign them to appropriate function pointers. This helps each filesystem implement superblock operations as per its layout of on-disk superblock and hide that logic under a common interface. Struct super_operations is defined in <linux/fs.h>:

struct super_operations {
struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *);

void (*dirty_inode) (struct inode *, int flags);
int (*write_inode) (struct inode *, struct writeback_control *wbc);
int (*drop_inode) (struct inode *);
void (*evict_inode) (struct inode *);
void (*put_super) (struct super_block *);
int (*sync_fs)(struct super_block *sb, int wait);
int (*freeze_super) (struct super_block *);
int (*freeze_fs) (struct super_block *);
int (*thaw_super) (struct super_block *);
int (*unfreeze_fs) (struct super_block *);
int (*statfs) (struct dentry *, struct kstatfs *);
int (*remount_fs) (struct super_block *, int *, char *);
void (*umount_begin) (struct super_block *);

int (*show_options)(struct seq_file *, struct dentry *);
int (*show_devname)(struct seq_file *, struct dentry *);
int (*show_path)(struct seq_file *, struct dentry *);
int (*show_stats)(struct seq_file *, struct dentry *);
#ifdef CONFIG_QUOTA
ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
struct dquot **(*get_dquots)(struct inode *);
#endif
int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
long (*nr_cached_objects)(struct super_block *,
struct shrink_control *);
long (*free_cached_objects)(struct super_block *,
struct shrink_control *);
};

All elements in this structure point to functions that operate on the superblock object. All these operations are only called from a process context and without any locks being held, unless specified. Let's look at few important ones here:

  • alloc_inode: This method is used to create and allocate space for the new inode object and initialize it under the superblock.
  • destroy_inode: This destroys the given inode object and frees resources allocated for the inode. This is only used if alloc_inode was defined.
  • dirty_inode: This is called by the VFS to mark a dirty inode (when inode is modified).
  • write_inode: VFS invokes this method when it needs to write an inode on to the disk. The second argument points to struct writeback_control, a structure that tells the writeback code what to do.
  • put_super: This is invoked when VFS needs to free the superblock.
  • sync_fs: This is invoked to synchronize filesystem data with that of the underlying block device.
  • statfs: Invoked to get filesystem statistics for the VFS.
  • remount_fs: Invoked when the filesystem needs to be remounted.
  • umount_begin: Invoked when the VFS is unmounting a filesystem.
  • show_options: Invoked by VFS to show mount options.
  • quota_read: Invoked by VFS to read from the filesystem quota file.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.230.82