socket fs(1)
来源:互联网 发布:周末午夜光明知乎 编辑:程序博客网 时间:2024/06/06 02:44
/*******************************************************/
sock_init函数的主要功能是赋值全局变量sock_mnt:
static struct vfsmount *sock_mnt __read_mostly;
core_initcall(sock_init); /* early initcall */
static int __init sock_init(void)
{
int err;
/*
* Initialize sock SLAB cache.
*/
sk_init();
/*
* Initialize skbuff SLAB cache
*/
skb_init();
/*
* Initialize the protocols module.
*/
init_inodecache();
err = register_filesystem(&sock_fs_type);
sock_mnt = kern_mount(&sock_fs_type);
/* The real protocol initialization is performed in later initcalls.
*/
netfilter_init();
return err;
}
函数sock_init里主要是相关结构体slab的初始化和文件系统相关的操作。
/*************************************************************************************/
/*这里首先涉及的数据类型为file_system_type*/
crash> file_system_type
struct file_system_type {
const char *name;
int fs_flags;
struct dentry *(*mount)(struct file_system_type *, int, const char *, void *);
void (*kill_sb)(struct super_block *);
struct module *owner;
struct file_system_type *next;
struct hlist_head fs_supers;
struct lock_class_key s_lock_key;
struct lock_class_key s_umount_key;
struct lock_class_key s_vfs_rename_key;
struct lock_class_key i_lock_key;
struct lock_class_key i_mutex_key;
struct lock_class_key i_mutex_dir_key;
}
SIZE: 28
/*sockfs的文件系统类型为sock_fs_type:主要的函数为mount*/
static struct file_system_type sock_fs_type = {
.name = "sockfs",
.mount = sockfs_mount,
.kill_sb = kill_anon_super,
};
/**
* register_filesystem - register a new filesystem
* @fs: the file system structure
*
* Adds the file system passed to the list of file systems the kernel
* is aware of for mount and other syscalls. Returns 0 on success,
* or a negative errno code on an error.
*
* The &struct file_system_type that is passed is linked into the kernel
* structures and must not be freed until the file system has been
* unregistered.
*/
int register_filesystem(struct file_system_type * fs)
{
int res = 0;
struct file_system_type ** p;
BUG_ON(strchr(fs->name, '.'));
if (fs->next)
return -EBUSY;
write_lock(&file_systems_lock);
p = find_filesystem(fs->name, strlen(fs->name));
if (*p)
res = -EBUSY;
else
*p = fs;/*使用二级指针,到这里才赋值到file_system_type全局变量*/
write_unlock(&file_systems_lock);
return res;
}
static struct file_system_type *file_systems;
/*根据file_systems可以找到所有的file system type.*/
/*************************************************************************************/
#define kern_mount(type) kern_mount_data(type, NULL)
struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
{
struct vfsmount *mnt;
mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
if (!IS_ERR(mnt)) {
/*
* it is a longterm mount, don't release mnt until
* we unmount before file sys is unregistered
*/
mnt_make_longterm(mnt);
}
return mnt;
}
/*总的数据结构有关vfsmount: dentry and super_block*/
crash> vfsmount
struct vfsmount {
struct dentry *mnt_root;
struct super_block *mnt_sb;
int mnt_flags;
}
struct vfsmount *
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
{
struct mount *mnt;
struct dentry *root;
if (!type)
return ERR_PTR(-ENODEV);
/*首先得到结构体mount*/
mnt = alloc_vfsmnt(name);
if (!mnt)
return ERR_PTR(-ENOMEM);
if (flags & MS_KERNMOUNT)
mnt->mnt.mnt_flags = MNT_INTERNAL;
/*根据注册的文件系统类型得到dentry*/
root = mount_fs(type, flags, name, data);
if (IS_ERR(root)) {
free_vfsmnt(mnt);
return ERR_CAST(root);
}
/*根据mount赋值vfsmount,并返回结构体vfsmount*/
mnt->mnt.mnt_root = root;
mnt->mnt.mnt_sb = root->d_sb;
mnt->mnt_mountpoint = mnt->mnt.mnt_root;
mnt->mnt_parent = mnt;
br_write_lock(vfsmount_lock);
list_add_tail(&mnt->mnt_instance, &root->d_sb->s_mounts);
br_write_unlock(vfsmount_lock);
return &mnt->mnt;
}
/*vfs_kern_mount -> alloc_vfsmnt引入了数据结构mount, vfsmount是mount的一个成员*/
static struct mount *alloc_vfsmnt(const char *name)
{
struct mount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
if (mnt) {
---;
}
return mnt;
}
crash> struct mount
struct mount {
struct list_head mnt_hash;
struct mount *mnt_parent;
struct dentry *mnt_mountpoint;
struct vfsmount mnt;
struct mnt_pcp *mnt_pcp;
atomic_t mnt_longterm;
struct list_head mnt_mounts;
struct list_head mnt_child;
struct list_head mnt_instance;
const char *mnt_devname;
struct list_head mnt_list;
struct list_head mnt_expire;
struct list_head mnt_share;
struct list_head mnt_slave_list;
struct list_head mnt_slave;
struct mount *mnt_master;
struct mnt_namespace *mnt_ns;
struct hlist_head mnt_fsnotify_marks;
__u32 mnt_fsnotify_mask;
int mnt_id;
int mnt_group_id;
int mnt_expiry_mark;
int mnt_pinned;
int mnt_ghosts;
}
SIZE: 140
/*vfs_kern_mount -> mount_fs 引入了数据结构dentry, vfsmount是mount的一个成员
*这里调用函数sockfs_mount生成了 dentry, super_block and inode.
*/
struct dentry *
mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
{
struct dentry *root;
struct super_block *sb;
root = type->mount(type, flags, name, data);
if (IS_ERR(root)) {
error = PTR_ERR(root);
goto out_free_secdata;
}
sb = root->d_sb;
return root;
}
/* super_block: Stores information concerning a mounted filesystem.
* For disk-based filesystems, this object usually corresponds to a
* filesystem control block stored on disk.[该信息存在磁盘上]
* super_block是怎样创建的?[创建一个,然后加入到链表super_blocks中]
* sget(file_system_type, ,) -> alloc_super(file_system_type) -> list_add_tail(&s->s_list, &super_blocks);
*/
crash> super_block
struct super_block {
struct list_head s_list;
dev_t s_dev;
unsigned char s_dirt;
unsigned char s_blocksize_bits;
unsigned long s_blocksize;
loff_t s_maxbytes;
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_magic;
struct dentry *s_root;
struct rw_semaphore s_umount;
struct mutex s_lock;
int s_count;
atomic_t s_active;
const struct xattr_handler **s_xattr;
struct list_head s_inodes;
struct hlist_bl_head s_anon;
struct list_head *s_files;
struct list_head s_mounts;
struct list_head s_dentry_lru;
int s_nr_dentry_unused;
spinlock_t s_inode_lru_lock;
struct list_head s_inode_lru;
int s_nr_inodes_unused;
struct block_device *s_bdev;
struct backing_dev_info *s_bdi;
struct mtd_info *s_mtd;
struct hlist_node s_instances;
struct quota_info s_dquot;
int s_frozen;
wait_queue_head_t s_wait_unfrozen;
char s_id[32];
u8 s_uuid[16];
void *s_fs_info;
unsigned int s_max_links;
fmode_t s_mode;
u32 s_time_gran;
struct mutex s_vfs_rename_mutex;
char *s_subtype;
char *s_options;
const struct dentry_operations *s_d_op;
int cleancache_poolid;
struct shrinker s_shrink;
atomic_long_t s_remove_count;
int s_readonly_remount;
}
SIZE: 576
static struct dentry *sockfs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
return mount_pseudo(fs_type, "socket:", &sockfs_ops,
&sockfs_dentry_operations, SOCKFS_MAGIC);
}
struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name,
const struct super_operations *ops,
const struct dentry_operations *dops, unsigned long magic)
{
/*先得到super_block*/
struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
struct dentry *dentry;
struct inode *root;
struct qstr d_name = {.name = name, .len = strlen(name)};
if (IS_ERR(s))
return ERR_CAST(s);
s->s_flags = MS_NOUSER;
s->s_maxbytes = MAX_LFS_FILESIZE;
s->s_blocksize = PAGE_SIZE;
s->s_blocksize_bits = PAGE_SHIFT;
s->s_magic = magic;
s->s_op = ops ? ops : &simple_super_operations;
s->s_time_gran = 1;
/*根据super_block得到inode*/
root = new_inode(s);
if (!root)
goto Enomem;
/*
* since this is the first inode, make it number 1. New inodes created
* after this must take care not to collide with it (by passing
* max_reserved of 1 to iunique).
*/
root->i_ino = 1;
root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
/*根据super_block得到dentry*/
dentry = __d_alloc(s, &d_name);
if (!dentry) {
iput(root);
goto Enomem;
}
d_instantiate(dentry, root);
s->s_root = dentry;
s->s_d_op = dops;
s->s_flags |= MS_ACTIVE;
return dget(s->s_root);
Enomem:
deactivate_locked_super(s);
return ERR_PTR(-ENOMEM);
}
/**
* new_inode - obtain an inode
* @sb: superblock
*
* Allocates a new inode for given superblock.
*
* new_inode_pseudo - obtain an inode
* @sb: superblock
*
* Allocates a new inode for given superblock.
* Inode wont be chained in superblock s_inodes list
*/
struct inode *new_inode(struct super_block *sb)
{
struct inode *inode;
spin_lock_prefetch(&inode_sb_list_lock);
inode = new_inode_pseudo(sb);
if (inode)
inode_sb_list_add(inode);
return inode;
}
/*The inode object Stores general information about a specific file.[存在磁盘上]
*For disk-based filesystems, this object usually corresponds to a file control block stored on disk.
*Each inode object is associated with an inode number, which uniquely identifies the file within the filesystem.
*/
crash> inode
struct inode {
umode_t i_mode;
unsigned short i_opflags;
uid_t i_uid;
gid_t i_gid;
unsigned int i_flags;
const struct inode_operations *i_op;
struct super_block *i_sb;
struct address_space *i_mapping;
unsigned long i_ino;
union {
const unsigned int i_nlink;
unsigned int __i_nlink;
};
dev_t i_rdev;
struct timespec i_atime;
struct timespec i_mtime;
struct timespec i_ctime;
spinlock_t i_lock;
unsigned short i_bytes;
blkcnt_t i_blocks;
loff_t i_size;
seqcount_t i_size_seqcount;
unsigned long i_state;
struct mutex i_mutex;
unsigned long dirtied_when;
struct hlist_node i_hash;
struct list_head i_wb_list;
struct list_head i_lru;
struct list_head i_sb_list;
union {
struct list_head i_dentry;
struct rcu_head i_rcu;
};
atomic_t i_count;
unsigned int i_blkbits;
u64 i_version;
atomic_t i_dio_count;
atomic_t i_writecount;
const struct file_operations *i_fop;
struct file_lock *i_flock;
struct address_space i_data;
struct list_head i_devices;
union {
struct pipe_inode_info *i_pipe;
struct block_device *i_bdev;
struct cdev *i_cdev;
};
__u32 i_generation;
__u32 i_fsnotify_mask;
struct hlist_head i_fsnotify_marks;
void *i_private;
}
SIZE: 344
/*The dentry object
*Stores information about the linking of a directory entry (that is, a particular name of the file)
*with the corresponding file. Each disk-based filesystem stores this information in its own
*particular way on disk.【存在磁盘上】
* mount_pseudo -> __d_alloc ->生成新的dentry.
*/
struct dentry {
/* RCU lookup touched fields */
unsigned int d_flags; /* protected by d_lock */
seqcount_t d_seq; /* per dentry seqlock */
struct hlist_bl_node d_hash; /* lookup hash list */
struct dentry *d_parent; /* parent directory */
struct qstr d_name;
struct inode *d_inode; /* Where the name belongs to - NULL is
* negative */
unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
/* Ref lookup also touches following */
unsigned int d_count; /* protected by d_lock */
spinlock_t d_lock; /* per dentry lock */
const struct dentry_operations *d_op;
struct super_block *d_sb; /* The root of the dentry tree */
unsigned long d_time; /* used by d_revalidate */
void *d_fsdata; /* fs-specific data */
struct list_head d_lru; /* LRU list */
/*
* d_child and d_rcu can share memory
*/
union {
struct list_head d_child; /* child of parent list */
struct rcu_head d_rcu;
} d_u;
struct list_head d_subdirs; /* our children */
struct list_head d_alias; /* inode alias list */
};
/*************************************************************************************/
file 又是怎样和上面的数据结构发生关系的那?
/*The file object
Stores information about the interaction between an open file and a process. This information
exists only in kernel memory during the period when a process has the file open.
*/
crash> file
struct file {
union {
struct list_head fu_list;
struct rcu_head fu_rcuhead;
} f_u;
struct path f_path;
const struct file_operations *f_op;
spinlock_t f_lock;
int f_sb_list_cpu;
atomic_long_t f_count;
unsigned int f_flags;
fmode_t f_mode;
loff_t f_pos;
struct fown_struct f_owner;
const struct cred *f_cred;
struct file_ra_state f_ra;
u64 f_version;
void *private_data;
struct list_head f_ep_links;
struct list_head f_tfile_llink;
struct address_space *f_mapping;
}
SIZE: 152
crash> file_operations
struct file_operations {
struct module *owner;
loff_t (*llseek)(struct file *, loff_t, int);
ssize_t (*read)(struct file *, char *, size_t, loff_t *);
ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
ssize_t (*aio_read)(struct kiocb *, const struct iovec *, unsigned long, loff_t);
ssize_t (*aio_write)(struct kiocb *, const struct iovec *, unsigned long, loff_t);
int (*readdir)(struct file *, void *, filldir_t);
unsigned int (*poll)(struct file *, struct poll_table_struct *);
long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);
long (*compat_ioctl)(struct file *, unsigned int, unsigned long);
int (*mmap)(struct file *, struct vm_area_struct *);
int (*open)(struct inode *, struct file *);
int (*flush)(struct file *, fl_owner_t);
int (*release)(struct inode *, struct file *);
int (*fsync)(struct file *, loff_t, loff_t, int);
int (*aio_fsync)(struct kiocb *, int);
int (*fasync)(int, struct file *, int);
int (*lock)(struct file *, int, struct file_lock *);
ssize_t (*sendpage)(struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
int (*check_flags)(int);
int (*flock)(struct file *, int, struct file_lock *);
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
int (*setlease)(struct file *, long, struct file_lock **);
long (*fallocate)(struct file *, int, loff_t, loff_t);
}
SIZE: 104
sock_init函数的主要功能是赋值全局变量sock_mnt:
static struct vfsmount *sock_mnt __read_mostly;
core_initcall(sock_init); /* early initcall */
static int __init sock_init(void)
{
int err;
/*
* Initialize sock SLAB cache.
*/
sk_init();
/*
* Initialize skbuff SLAB cache
*/
skb_init();
/*
* Initialize the protocols module.
*/
init_inodecache();
err = register_filesystem(&sock_fs_type);
sock_mnt = kern_mount(&sock_fs_type);
/* The real protocol initialization is performed in later initcalls.
*/
netfilter_init();
return err;
}
函数sock_init里主要是相关结构体slab的初始化和文件系统相关的操作。
/*************************************************************************************/
/*这里首先涉及的数据类型为file_system_type*/
crash> file_system_type
struct file_system_type {
const char *name;
int fs_flags;
struct dentry *(*mount)(struct file_system_type *, int, const char *, void *);
void (*kill_sb)(struct super_block *);
struct module *owner;
struct file_system_type *next;
struct hlist_head fs_supers;
struct lock_class_key s_lock_key;
struct lock_class_key s_umount_key;
struct lock_class_key s_vfs_rename_key;
struct lock_class_key i_lock_key;
struct lock_class_key i_mutex_key;
struct lock_class_key i_mutex_dir_key;
}
SIZE: 28
/*sockfs的文件系统类型为sock_fs_type:主要的函数为mount*/
static struct file_system_type sock_fs_type = {
.name = "sockfs",
.mount = sockfs_mount,
.kill_sb = kill_anon_super,
};
/**
* register_filesystem - register a new filesystem
* @fs: the file system structure
*
* Adds the file system passed to the list of file systems the kernel
* is aware of for mount and other syscalls. Returns 0 on success,
* or a negative errno code on an error.
*
* The &struct file_system_type that is passed is linked into the kernel
* structures and must not be freed until the file system has been
* unregistered.
*/
int register_filesystem(struct file_system_type * fs)
{
int res = 0;
struct file_system_type ** p;
BUG_ON(strchr(fs->name, '.'));
if (fs->next)
return -EBUSY;
write_lock(&file_systems_lock);
p = find_filesystem(fs->name, strlen(fs->name));
if (*p)
res = -EBUSY;
else
*p = fs;/*使用二级指针,到这里才赋值到file_system_type全局变量*/
write_unlock(&file_systems_lock);
return res;
}
static struct file_system_type *file_systems;
/*根据file_systems可以找到所有的file system type.*/
/*************************************************************************************/
#define kern_mount(type) kern_mount_data(type, NULL)
struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
{
struct vfsmount *mnt;
mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
if (!IS_ERR(mnt)) {
/*
* it is a longterm mount, don't release mnt until
* we unmount before file sys is unregistered
*/
mnt_make_longterm(mnt);
}
return mnt;
}
/*总的数据结构有关vfsmount: dentry and super_block*/
crash> vfsmount
struct vfsmount {
struct dentry *mnt_root;
struct super_block *mnt_sb;
int mnt_flags;
}
struct vfsmount *
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
{
struct mount *mnt;
struct dentry *root;
if (!type)
return ERR_PTR(-ENODEV);
/*首先得到结构体mount*/
mnt = alloc_vfsmnt(name);
if (!mnt)
return ERR_PTR(-ENOMEM);
if (flags & MS_KERNMOUNT)
mnt->mnt.mnt_flags = MNT_INTERNAL;
/*根据注册的文件系统类型得到dentry*/
root = mount_fs(type, flags, name, data);
if (IS_ERR(root)) {
free_vfsmnt(mnt);
return ERR_CAST(root);
}
/*根据mount赋值vfsmount,并返回结构体vfsmount*/
mnt->mnt.mnt_root = root;
mnt->mnt.mnt_sb = root->d_sb;
mnt->mnt_mountpoint = mnt->mnt.mnt_root;
mnt->mnt_parent = mnt;
br_write_lock(vfsmount_lock);
list_add_tail(&mnt->mnt_instance, &root->d_sb->s_mounts);
br_write_unlock(vfsmount_lock);
return &mnt->mnt;
}
/*vfs_kern_mount -> alloc_vfsmnt引入了数据结构mount, vfsmount是mount的一个成员*/
static struct mount *alloc_vfsmnt(const char *name)
{
struct mount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
if (mnt) {
---;
}
return mnt;
}
crash> struct mount
struct mount {
struct list_head mnt_hash;
struct mount *mnt_parent;
struct dentry *mnt_mountpoint;
struct vfsmount mnt;
struct mnt_pcp *mnt_pcp;
atomic_t mnt_longterm;
struct list_head mnt_mounts;
struct list_head mnt_child;
struct list_head mnt_instance;
const char *mnt_devname;
struct list_head mnt_list;
struct list_head mnt_expire;
struct list_head mnt_share;
struct list_head mnt_slave_list;
struct list_head mnt_slave;
struct mount *mnt_master;
struct mnt_namespace *mnt_ns;
struct hlist_head mnt_fsnotify_marks;
__u32 mnt_fsnotify_mask;
int mnt_id;
int mnt_group_id;
int mnt_expiry_mark;
int mnt_pinned;
int mnt_ghosts;
}
SIZE: 140
/*vfs_kern_mount -> mount_fs 引入了数据结构dentry, vfsmount是mount的一个成员
*这里调用函数sockfs_mount生成了 dentry, super_block and inode.
*/
struct dentry *
mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
{
struct dentry *root;
struct super_block *sb;
root = type->mount(type, flags, name, data);
if (IS_ERR(root)) {
error = PTR_ERR(root);
goto out_free_secdata;
}
sb = root->d_sb;
return root;
}
/* super_block: Stores information concerning a mounted filesystem.
* For disk-based filesystems, this object usually corresponds to a
* filesystem control block stored on disk.[该信息存在磁盘上]
* super_block是怎样创建的?[创建一个,然后加入到链表super_blocks中]
* sget(file_system_type, ,) -> alloc_super(file_system_type) -> list_add_tail(&s->s_list, &super_blocks);
*/
crash> super_block
struct super_block {
struct list_head s_list;
dev_t s_dev;
unsigned char s_dirt;
unsigned char s_blocksize_bits;
unsigned long s_blocksize;
loff_t s_maxbytes;
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_magic;
struct dentry *s_root;
struct rw_semaphore s_umount;
struct mutex s_lock;
int s_count;
atomic_t s_active;
const struct xattr_handler **s_xattr;
struct list_head s_inodes;
struct hlist_bl_head s_anon;
struct list_head *s_files;
struct list_head s_mounts;
struct list_head s_dentry_lru;
int s_nr_dentry_unused;
spinlock_t s_inode_lru_lock;
struct list_head s_inode_lru;
int s_nr_inodes_unused;
struct block_device *s_bdev;
struct backing_dev_info *s_bdi;
struct mtd_info *s_mtd;
struct hlist_node s_instances;
struct quota_info s_dquot;
int s_frozen;
wait_queue_head_t s_wait_unfrozen;
char s_id[32];
u8 s_uuid[16];
void *s_fs_info;
unsigned int s_max_links;
fmode_t s_mode;
u32 s_time_gran;
struct mutex s_vfs_rename_mutex;
char *s_subtype;
char *s_options;
const struct dentry_operations *s_d_op;
int cleancache_poolid;
struct shrinker s_shrink;
atomic_long_t s_remove_count;
int s_readonly_remount;
}
SIZE: 576
static struct dentry *sockfs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
return mount_pseudo(fs_type, "socket:", &sockfs_ops,
&sockfs_dentry_operations, SOCKFS_MAGIC);
}
struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name,
const struct super_operations *ops,
const struct dentry_operations *dops, unsigned long magic)
{
/*先得到super_block*/
struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
struct dentry *dentry;
struct inode *root;
struct qstr d_name = {.name = name, .len = strlen(name)};
if (IS_ERR(s))
return ERR_CAST(s);
s->s_flags = MS_NOUSER;
s->s_maxbytes = MAX_LFS_FILESIZE;
s->s_blocksize = PAGE_SIZE;
s->s_blocksize_bits = PAGE_SHIFT;
s->s_magic = magic;
s->s_op = ops ? ops : &simple_super_operations;
s->s_time_gran = 1;
/*根据super_block得到inode*/
root = new_inode(s);
if (!root)
goto Enomem;
/*
* since this is the first inode, make it number 1. New inodes created
* after this must take care not to collide with it (by passing
* max_reserved of 1 to iunique).
*/
root->i_ino = 1;
root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
/*根据super_block得到dentry*/
dentry = __d_alloc(s, &d_name);
if (!dentry) {
iput(root);
goto Enomem;
}
d_instantiate(dentry, root);
s->s_root = dentry;
s->s_d_op = dops;
s->s_flags |= MS_ACTIVE;
return dget(s->s_root);
Enomem:
deactivate_locked_super(s);
return ERR_PTR(-ENOMEM);
}
/**
* new_inode - obtain an inode
* @sb: superblock
*
* Allocates a new inode for given superblock.
*
* new_inode_pseudo - obtain an inode
* @sb: superblock
*
* Allocates a new inode for given superblock.
* Inode wont be chained in superblock s_inodes list
*/
struct inode *new_inode(struct super_block *sb)
{
struct inode *inode;
spin_lock_prefetch(&inode_sb_list_lock);
inode = new_inode_pseudo(sb);
if (inode)
inode_sb_list_add(inode);
return inode;
}
/*The inode object Stores general information about a specific file.[存在磁盘上]
*For disk-based filesystems, this object usually corresponds to a file control block stored on disk.
*Each inode object is associated with an inode number, which uniquely identifies the file within the filesystem.
*/
crash> inode
struct inode {
umode_t i_mode;
unsigned short i_opflags;
uid_t i_uid;
gid_t i_gid;
unsigned int i_flags;
const struct inode_operations *i_op;
struct super_block *i_sb;
struct address_space *i_mapping;
unsigned long i_ino;
union {
const unsigned int i_nlink;
unsigned int __i_nlink;
};
dev_t i_rdev;
struct timespec i_atime;
struct timespec i_mtime;
struct timespec i_ctime;
spinlock_t i_lock;
unsigned short i_bytes;
blkcnt_t i_blocks;
loff_t i_size;
seqcount_t i_size_seqcount;
unsigned long i_state;
struct mutex i_mutex;
unsigned long dirtied_when;
struct hlist_node i_hash;
struct list_head i_wb_list;
struct list_head i_lru;
struct list_head i_sb_list;
union {
struct list_head i_dentry;
struct rcu_head i_rcu;
};
atomic_t i_count;
unsigned int i_blkbits;
u64 i_version;
atomic_t i_dio_count;
atomic_t i_writecount;
const struct file_operations *i_fop;
struct file_lock *i_flock;
struct address_space i_data;
struct list_head i_devices;
union {
struct pipe_inode_info *i_pipe;
struct block_device *i_bdev;
struct cdev *i_cdev;
};
__u32 i_generation;
__u32 i_fsnotify_mask;
struct hlist_head i_fsnotify_marks;
void *i_private;
}
SIZE: 344
/*The dentry object
*Stores information about the linking of a directory entry (that is, a particular name of the file)
*with the corresponding file. Each disk-based filesystem stores this information in its own
*particular way on disk.【存在磁盘上】
* mount_pseudo -> __d_alloc ->生成新的dentry.
*/
struct dentry {
/* RCU lookup touched fields */
unsigned int d_flags; /* protected by d_lock */
seqcount_t d_seq; /* per dentry seqlock */
struct hlist_bl_node d_hash; /* lookup hash list */
struct dentry *d_parent; /* parent directory */
struct qstr d_name;
struct inode *d_inode; /* Where the name belongs to - NULL is
* negative */
unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
/* Ref lookup also touches following */
unsigned int d_count; /* protected by d_lock */
spinlock_t d_lock; /* per dentry lock */
const struct dentry_operations *d_op;
struct super_block *d_sb; /* The root of the dentry tree */
unsigned long d_time; /* used by d_revalidate */
void *d_fsdata; /* fs-specific data */
struct list_head d_lru; /* LRU list */
/*
* d_child and d_rcu can share memory
*/
union {
struct list_head d_child; /* child of parent list */
struct rcu_head d_rcu;
} d_u;
struct list_head d_subdirs; /* our children */
struct list_head d_alias; /* inode alias list */
};
/*************************************************************************************/
file 又是怎样和上面的数据结构发生关系的那?
/*The file object
Stores information about the interaction between an open file and a process. This information
exists only in kernel memory during the period when a process has the file open.
*/
crash> file
struct file {
union {
struct list_head fu_list;
struct rcu_head fu_rcuhead;
} f_u;
struct path f_path;
const struct file_operations *f_op;
spinlock_t f_lock;
int f_sb_list_cpu;
atomic_long_t f_count;
unsigned int f_flags;
fmode_t f_mode;
loff_t f_pos;
struct fown_struct f_owner;
const struct cred *f_cred;
struct file_ra_state f_ra;
u64 f_version;
void *private_data;
struct list_head f_ep_links;
struct list_head f_tfile_llink;
struct address_space *f_mapping;
}
SIZE: 152
crash> file_operations
struct file_operations {
struct module *owner;
loff_t (*llseek)(struct file *, loff_t, int);
ssize_t (*read)(struct file *, char *, size_t, loff_t *);
ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
ssize_t (*aio_read)(struct kiocb *, const struct iovec *, unsigned long, loff_t);
ssize_t (*aio_write)(struct kiocb *, const struct iovec *, unsigned long, loff_t);
int (*readdir)(struct file *, void *, filldir_t);
unsigned int (*poll)(struct file *, struct poll_table_struct *);
long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);
long (*compat_ioctl)(struct file *, unsigned int, unsigned long);
int (*mmap)(struct file *, struct vm_area_struct *);
int (*open)(struct inode *, struct file *);
int (*flush)(struct file *, fl_owner_t);
int (*release)(struct inode *, struct file *);
int (*fsync)(struct file *, loff_t, loff_t, int);
int (*aio_fsync)(struct kiocb *, int);
int (*fasync)(int, struct file *, int);
int (*lock)(struct file *, int, struct file_lock *);
ssize_t (*sendpage)(struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
int (*check_flags)(int);
int (*flock)(struct file *, int, struct file_lock *);
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
int (*setlease)(struct file *, long, struct file_lock **);
long (*fallocate)(struct file *, int, loff_t, loff_t);
}
SIZE: 104
- socket fs(1)
- socket fs(2)
- socket fs(3)
- linux debug fs(1)
- FS
- fs
- fs
- fs
- fs
- fs
- fs
- FS
- 明明白白我的心--fs series(1)
- FS-V1、FS-M1、FS-M2、FS-T1、FS-T2
- Hadoop源码情景小析(1)fs -copyFromLocal
- Hadoop(1):权限问题以及Wrong FS错误
- fs寄存器
- FS寄存器
- 关于XBYTE的使用
- Pushlet实例解析
- C#加密解密小工具
- 给定数据段中找到第一个有效bit实现(文件系统)
- FORM表单中onclick()、submit()与onsubmit()的问题
- socket fs(1)
- 上报和分发消息的流程
- 浏览按钮操作
- Comt4j消息推送实例
- 浙工ACM1009
- 58. 给未来的消息
- DataTable to byte[]、DataTable to XML(string)
- OpenCV 范例程序调试
- c#字符串常用汇总