各种文件系统都必须实现超级块对象,该对象用于存储特定文件系统的信息,通常对应于存放在磁盘特定扇区中的文件系统超级块或文件系统控制块(所以称为超级块对象)。对于并非基于磁盘的文件系统(如基于内存的文件系统,比如
sysfs),它们会在使用现场创建超级块并将其保存到内存中。超级块对象由
super block
结构体表示,定义在文件《linux/fs.h》中,下面给出它的结构和各个域的描述:
structsuper_block { structlist_heads_list;/* Keep this first */ dev_t s_dev; /* search index; _not_ kdev_t */ unsignedchar s_blocksize_bits; unsignedlong s_blocksize; loff_t s_maxbytes; /* Max file size */ structfile_system_type *s_type; conststructsuper_operations *s_op; conststructdquot_operations *dq_op; conststructquotactl_ops *s_qcop; conststructexport_operations *s_export_op; unsignedlong s_flags; unsignedlong s_iflags; /* internal SB_I_* flags */ unsignedlong s_magic; structdentry *s_root; structrw_semaphores_umount; int s_count; atomic_t s_active; #ifdef CONFIG_SECURITY void *s_security; #endif conststructxattr_handler **s_xattr; #ifdef CONFIG_FS_ENCRYPTION conststructfscrypt_operations *s_cop; structkey *s_master_keys;/* master crypto keys in use */ #endif #ifdef CONFIG_FS_VERITY conststructfsverity_operations *s_vop; #endif #ifdef CONFIG_UNICODE structunicode_map *s_encoding; __u16 s_encoding_flags; #endif structhlist_bl_heads_roots;/* alternate root dentries for NFS */ structlist_heads_mounts;/* list of mounts; _not_ for fs use */ structblock_device *s_bdev; structbacking_dev_info *s_bdi; structmtd_info *s_mtd; structhlist_nodes_instances; unsignedint s_quota_types; /* Bitmask of supported quota types */ structquota_infos_dquot;/* Diskquota specific options */
structsb_writerss_writers;
/* * Keep s_fs_info, s_time_gran, s_fsnotify_mask, and * s_fsnotify_marks together for cache efficiency. They are frequently * accessed and rarely modified. */ void *s_fs_info; /* Filesystem private info */
/* Granularity of c/m/atime in ns (cannot be worse than a second) */ u32 s_time_gran; /* Time limits for c/m/atime in seconds */ time64_t s_time_min; time64_t s_time_max; #ifdef CONFIG_FSNOTIFY __u32 s_fsnotify_mask; structfsnotify_mark_connector __rcu *s_fsnotify_marks; #endif
/* * The next field is for VFS *only*. No filesystems have any business * even looking at it. You had been warned. */ structmutexs_vfs_rename_mutex;/* Kludge */
/* * Filesystem subtype. If non-empty the filesystem type field * in /proc/mounts will be "type.subtype" */ constchar *s_subtype;
conststructdentry_operations *s_d_op;/* default d_op for dentries */
/* * Saved pool identifier for cleancache (-1 means none) */ int cleancache_poolid;
/* Number of inodes with nlink == 0 but still referenced */ atomic_long_t s_remove_count;
/* * Number of inode/mount/sb objects that are being watched, note that * inodes objects are currently double-accounted. */ atomic_long_t s_fsnotify_connectors;
/* Being remounted read-only */ int s_readonly_remount;
/* per-sb errseq_t for reporting writeback errors via syncfs */ errseq_t s_wb_err;
/* * Owning user namespace and default context in which to * interpret filesystem uids, gids, quotas, device nodes, * xattrs and security labels. */ structuser_namespace *s_user_ns;
/* * The list_lru structure is essentially just a pointer to a table * of per-node lru lists, each of which has its own spinlock. * There is no need to put them into separate cachelines. */ structlist_lrus_dentry_lru; structlist_lrus_inode_lru; structrcu_headrcu; structwork_structdestroy_work;
/* * Keep mostly read-only and often accessed (especially for * the RCU path lookup and 'stat' data) fields at the beginning * of the 'struct inode' */ structinode { umode_t i_mode; unsignedshort i_opflags; kuid_t i_uid; kgid_t i_gid; unsignedint i_flags;
structdentry { /* RCU lookup touched fields */ unsignedint d_flags; /* protected by d_lock */ seqcount_spinlock_t d_seq; /* per dentry seqlock */ structhlist_bl_noded_hash;/* lookup hash list */ structdentry *d_parent;/* parent directory */ structqstrd_name; structinode *d_inode;/* Where the name belongs to - NULL is * negative */ unsignedchar d_iname[DNAME_INLINE_LEN]; /* small names */
/* Ref lookup also touches following */ structlockrefd_lockref;/* per-dentry lock and refcount */ conststructdentry_operations *d_op; structsuper_block *d_sb;/* The root of the dentry tree */ unsignedlong d_time; /* used by d_revalidate */ void *d_fsdata; /* fs-specific data */
union { structlist_headd_lru;/* LRU list */ wait_queue_head_t *d_wait; /* in-lookup ones only */ }; structlist_headd_child;/* child of parent list */ structlist_headd_subdirs;/* our children */ /* * d_alias and d_rcu can share memory */ union { structhlist_noded_alias;/* inode alias list */ structhlist_bl_noded_in_lookup_hash;/* only for in-lookup ones */ structrcu_headd_rcu; } d_u; } __randomize_layout;
structfile { union { structllist_nodefu_llist; structrcu_headfu_rcuhead; } f_u; structpathf_path; structinode *f_inode;/* cached value */ conststructfile_operations *f_op;
/* * Protects f_ep, f_flags. * Must not be taken from IRQ context. */ spinlock_t f_lock; enumrw_hintf_write_hint; atomic_long_t f_count; unsignedint f_flags; fmode_t f_mode; structmutexf_pos_lock; loff_t f_pos; structfown_structf_owner; conststructcred *f_cred; structfile_ra_statef_ra;
u64 f_version; #ifdef CONFIG_SECURITY void *f_security; #endif /* needed for tty driver, and maybe others */ void *private_data;
#ifdef CONFIG_EPOLL /* Used by fs/eventpoll.c to link all the hooks to this file */ structhlist_head *f_ep; #endif/* #ifdef CONFIG_EPOLL */ structaddress_space *f_mapping; errseq_t f_wb_err; errseq_t f_sb_err; /* for syncfs */ } __randomize_layout __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
structvfsmount { structdentry *mnt_root;/* root of the mounted tree */ structsuper_block *mnt_sb;/* pointer to superblock */ int mnt_flags; structuser_namespace *mnt_userns; } __randomize_layout;
structfdtable __rcu *fdt; structfdtablefdtab; /* * written part on a separate cache line in SMP */ spinlock_t file_lock ____cacheline_aligned_in_smp; unsignedint next_fd; unsignedlong close_on_exec_init[1]; unsignedlong open_fds_init[1]; unsignedlong full_fds_bits_init[1]; structfile __rcu * fd_array[NR_OPEN_DEFAULT]; };