Linux内核研究:我的虚拟文件系统(linux)

王朝system·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

hello.c

代码:

#include "hello.h"

struct inode * hello_get_inode(struct super_block *, int, struct hello_dir_entry *);

int hello_readdir(struct file * filp, void * dirent, filldir_t filldir)

{

printk("hello_readdir\n");

struct hello_dir_entry * de;

unsigned int ino;

int i;

struct inode *inode = filp-f_dentry-d_inode;

ino = inode-i_ino;

de = (struct hello_dir_entry *) inode-u.generic_ip;

if (!de)

return -EINVAL;

i = filp-f_pos;

switch (i) {

case 0:

if (filldir(dirent, ".", 1, i, ino, DT_DIR)

return 0;

i++;

filp-f_pos++;

/* fall through */

case 1:

if (filldir(dirent, "..", 2, i,

filp-f_dentry-d_parent-d_inode-i_ino,

DT_DIR)

return 0;

i++;

filp-f_pos++;

/* fall through */

default:

de = de-subdir;

i -= 2;

for (;;) {

if (!de)

return 1;

if (!i)

break;

de = de-next;

i--;

}

do {

if (filldir(dirent, de-name, de-namelen, filp-f_pos,

de-low_ino, de-mode 12)

return 0;

filp-f_pos++;

de = de-next;

} while (de);

}

return 1;

}

int hello_d_revalidate(struct dentry *res, int i){printk("d_revalidate\n");return 0;}

int hello_d_hash(struct dentry *res, struct qstr *name){printk("d_hash\n");return 0;}

int hello_d_compare(struct dentry *res, struct qstr *name, struct qstr *old)

{printk("d_compare\n");return 0;}

int hello_d_delete(struct dentry *res){printk("d_delete\n");return 0;}

void hello_d_release(struct dentry *res){printk("d_release\n");}

void hello_d_iput(struct dentry *res, struct inode *inode){printk("d_iput\n");}

struct dentry_operations hello_lookup_dops = {

/*d_revalidate:

hello_d_revalidate,

d_hash:

hello_d_hash,

d_compare:

hello_d_compare,*/

d_delete:

hello_d_delete,

d_release:

hello_d_release,

/*d_iput:

hello_d_iput*/

};

struct dentry *hello_lookup(struct inode * dir, struct dentry *dentry)

{

struct inode *inode;

struct hello_dir_entry * de;

int error;

error = -ENOENT;

inode = NULL;

de = (struct hello_dir_entry *) dir-u.generic_ip;

if (de) {

for (de = de-subdir; de ; de = de-next) {

if (!de || !de-low_ino)

continue;

if (de-namelen != dentry-d_name.len)

continue;

if (!memcmp(dentry-d_name.name, de-name, de-namelen)) {

int ino = de-low_ino;

error = -EINVAL;

inode = hello_get_inode(dir-i_sb, ino, de);

break;

}

}

}

if (inode) {

dentry-d_op = &hello_lookup_dops;

d_add(dentry, inode);

return NULL;

}

return ERR_PTR(error);

}

/************************************************************************************************************/

static struct inode_operations hello_root_inode_operations = {

lookup:

hello_lookup,

};

static struct file_operations hello_file_operations = {

readdir:

hello_readdir,

};

struct hello_dir_entry hello_root = {

low_ino:

HELLO_ROOT_INO,

namelen:

5,

name:

"/hello",

mode:

S_IFDIR | S_IRUGO | S_IXUGO,

nlink:

2,

hello_iops:

&hello_root_inode_operations,

hello_fops:

&hello_file_operations,

parent:

&hello_root,

};

struct inode * hello_get_inode(struct super_block * sb, int ino,

struct hello_dir_entry * de)

{

printk("hello_get_inode\n");

struct inode * inode;

de_get(de);

inode = iget(sb, ino);

if (!inode)

goto out_fail;

inode-u.generic_ip = (void *) de;

if (de) {

if (de-mode) {

inode-i_mode = de-mode;

inode-i_uid = de-uid;

inode-i_gid = de-gid;

}

if (de-size)

inode-i_size = de-size;

if (de-nlink)

inode-i_nlink = de-nlink;

if (de-owner)

__MOD_INC_USE_COUNT(de-owner);

if (de-hello_iops)

inode-i_op = de-hello_iops;

if (de-hello_fops)

inode-i_fop = de-hello_fops;

}

out:

return inode;

out_fail:

de_put(de);

goto out;

}

/***********************************************************************************************************/

void d_instantiate(struct dentry *entry, struct inode * inode)

{

printk("d_instantiate\n");

if (!list_empty(&entry-d_alias)) BUG();

spin_lock(&dcache_lock);

if (inode)

list_add(&entry-d_alias, &inode-i_dentry);

entry-d_inode = inode;

spin_unlock(&dcache_lock);

}

struct dentry * d_alloc_root(struct inode * root_inode)

{

struct dentry *res = NULL;

printk("d_alloc_root\n");

if (root_inode) {

res = d_alloc(NULL, &(const struct qstr) { "/", 1, 0 });

if (res) {

res-d_sb = root_inode-i_sb;

res-d_parent = res;

d_instantiate(res, root_inode);

}

}

return res;

}

void force_delete(struct inode *inode)

{

printk("force_delete\n");

struct hello_dir_entry *de = inode-u.generic_ip;

if (atomic_read(&inode-i_count) == 1)

inode-i_nlink = 0;

if (atomic_dec_and_test(&de-count))

printk("hello_root.count: %d\n", atomic_read(&de-count));

}

static void hello_delete_inode(struct inode *inode)

{

printk("hello_delete_inode\n");

struct hello_dir_entry *de = inode-u.generic_ip;

inode-i_state = I_CLEAR;

/*if (de) {

if (de-owner)

__MOD_DEC_USE_COUNT(de-owner);

de_put(de);

}*/

}

static void hello_read_inode(struct inode * inode)

{

printk("hello_read_inode\n");

inode-i_mtime = inode-i_atime = inode-i_ctime = CURRENT_TIME;

}

static int hello_statfs(struct super_block *sb, struct statfs *buf)

{

printk("hello_statfs\n");

return 0;

}

void hello_write_super(struct super_block *s)

{

printk("write_super\n");

}

static struct super_operations hello_sops = {

read_inode:

hello_read_inode,

put_inode:

force_delete,

delete_inode:

hello_delete_inode,

write_super:

hello_w

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航