文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>中文版的个人文件系统

中文版的个人文件系统

时间:2006-08-25  来源:lonelyair

#include "hello.h"

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

/*这个函数是直接从linux复制过来的,作用就是显示目录里的文件名,没有这个
函数也行只是你用ls、dir命令看不到目录下的文件。*/
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) < 0)
                                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) < 0)
                                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) < 0)
                                        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*/
};

/*读文件节点,这个函数是被real_lookup函数调用的,具体调用是这里dir->;i_op->;lookup(dir, dentry);作用是从磁盘读文件节点填充inode结构。我这里用hello_dir_entry结构填充的*/

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,
};

/*填充inode结构*/
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);
}
/*创建根目录的dentry结构*/

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);/*把根目录的inode结构安装到dentry结构里*/
                }
        }
        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_write_super,
        /*statfs:                hello_statfs,*/
};

struct dentry_operations hello_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 super_block *hello_read_super(struct super_block *s, void *data,
                                    int silent)
{
printk("hello_read_super\n");       
        struct inode * root_inode;

        s->;s_blocksize = 1024;
        s->;s_blocksize_bits = 10;
        s->;s_magic = 0;
        s->;s_op = &hello_sops;
        root_inode = hello_get_inode(s, HELLO_ROOT_INO, &hello_root);
        if (!root_inode)
                goto out_no_root;

        s->;s_root = d_alloc_root(root_inode);
        if (!s->;s_root)
                goto out_no_root;
        s->;s_root->;d_op = &hello_dops;
        return s;

out_no_root:
        printk("hello_read_super: get root inode failed\n");
        iput(root_inode);
        return NULL;
} hello.h

CODE:
[Copy to clipboard]
#include <linux/kernel.h>;
#include <linux/module.h>;

#include <linux/fs.h>;
#include <linux/wrapper.h>;
#include <linux/slab.h>;
#include <linux/wait.h>;
#include <linux/poll.h>;

#include <linux/mm.h>;
#include <linux/pagemap.h>;

#include <asm/uaccess.h>;
#include <asm/semaphore.h>;

#define HELLO_ROOT_INO 1
       
typedef        int (read_hello_t)(char *page, char **start, off_t off,
                          int count, int *eof, void *data);
typedef        int (write_hello_t)(struct file *file, const char *buffer,
                           unsigned long count, void *data);
typedef int (get_info_t)(char *, char **, off_t, int);

struct hello_dir_entry {
        unsigned short low_ino;
        unsigned short namelen;
        const char *name;
        mode_t mode;
        nlink_t nlink;
        uid_t uid;
        gid_t gid;
        unsigned long size;
        struct inode_operations * hello_iops;
        struct file_operations * hello_fops;
        get_info_t *get_info;
        struct module *owner;
        struct hello_dir_entry *next, *parent, *subdir;
        void *data;
        read_hello_t *read_hello;
        write_hello_t *write_hello;
        atomic_t count;                /* use count */
        int deleted;                /* delete flag */
        kdev_t        rdev;
};

extern struct hello_dir_entry hello_root;
extern struct dentry *hello_lookup(struct inode *, struct dentry *);
extern int hello_misc_init(void);
extern struct super_block *hello_read_super(struct super_block *, void *, int);
extern void de_put(struct hello_dir_entry *);
extern struct hello_dir_entry * de_get(struct hello_dir_entry *);
extern int hello_readdir(struct file *, void *, filldir_t); /*这个文件的作用是创建虚拟文件树结构,相当于磁盘上的文件树,这里我就不注释了,有兴趣的自己看看吧,挺简单的*/
hello_entry.c

CODE:
[Copy to clipboard]
#include "hello.h"

static struct inode_operations hello_dir_inode_operations = {
        lookup:                hello_lookup,
};

struct hello_dir_entry * de_get(struct hello_dir_entry *de)
{
printk("de_get\n");
        if (de)
                atomic_inc(&de->;count);
        return de;
}

void inline free_hello_entry(struct hello_dir_entry *de)
{
printk("free_hello_entry\n");
        kfree(de);
}

void de_put(struct hello_dir_entry *de)
{
printk("de_put\n");
        if (de) {               
                if (!atomic_read(&de->;count)) {
                        printk("de_put: entry %s already free!\n", de->;name);
                        return;
                }

                if (atomic_dec_and_test(&de->;count))
                        free_hello_entry(de);
        }
}

static ssize_t
hello_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
{
        struct inode * inode = file->;f_dentry->;d_inode;
        char         *page;
        ssize_t        n;
        char        *start;
        struct hello_dir_entry * dp;

        dp = (struct hello_dir_entry *) inode->;u.generic_ip;
        if (!(page = (char*) __get_free_page(GFP_KERNEL)))
                return -ENOMEM;

        n = dp->;read_hello(page, &start, *ppos,0,  NULL, NULL);
        copy_to_user(buf, page, n);

        free_page((unsigned long) page);
        return n;
}

static ssize_t
hello_file_write(struct file * file, const char * buffer,
                size_t count, loff_t *ppos)
{
        struct inode *inode = file->;f_dentry->;d_inode;
        struct hello_dir_entry * dp;
       
        dp = (struct hello_dir_entry *) inode->;u.generic_ip;

        if (!dp->;write_hello)
                return -EIO;

        /* FIXME: does this routine need ppos?  probably... */
        return dp->;write_hello(file, buffer, count, dp->;data);
}

static loff_t
hello_file_lseek(struct file * file, loff_t offset, int origin)
{
        long long retval;

        switch (origin) {
                case 2:
                        offset += file->;f_dentry->;d_inode->;i_size;
                        break;
                case 1:
                        offset += file->;f_pos;
        }
        retval = -EINVAL;
        if (offset>;=0 && offset<=file->;f_dentry->;d_inode->;i_sb->;s_maxbytes) {
                if (offset != file->;f_pos) {
                        file->;f_pos = offset;
                        file->;f_reada = 0;
                }
                retval = offset;
        }
        return retval;
}

static struct file_operations hello_file_operations = {
        llseek:                hello_file_lseek,
        read:                hello_file_read,
        write:                hello_file_write,
};

static int hello_register(struct hello_dir_entry * dir, struct hello_dir_entry * dp)
{
printk("hello_register\n");
        dp->;low_ino = 2;
        dp->;next = dir->;subdir;
        dp->;parent = dir;
        dir->;subdir = dp;
        if (S_ISDIR(dp->;mode)) {
                if (dp->;hello_iops == NULL) {
                        dp->;hello_fops = NULL;
                        dp->;hello_iops = &hello_dir_inode_operations;
                }
                dir->;nlink++;
        } else if (S_ISREG(dp->;mode)) {
                if (dp->;hello_fops == NULL)
                        dp->;hello_fops = &hello_file_operations;
        }

        return 0;
}

static struct hello_dir_entry *hello_create(struct hello_dir_entry **parent,
                                          const char *name,
                                          mode_t mode,
                                          nlink_t nlink)
{
printk("hello_create\n");
        struct hello_dir_entry *ent = NULL;
        const char *fn = name;
        int len;

        len = strlen(name);
        *parent = &hello_root;

        ent = kmalloc(sizeof(struct hello_dir_entry) + len + 1, GFP_KERNEL);
        if (!ent) goto out;

        memset(ent, 0, sizeof(struct hello_dir_entry));
        memcpy(((char *) ent) + sizeof(struct hello_dir_entry), fn, len + 1);
        ent->;name = ((char *) ent) + sizeof(*ent);
        ent->;namelen = len;
        ent->;mode = mode;
        ent->;nlink = nlink;
out:
        return ent;
}

struct hello_dir_entry *create_hello_entry(const char *name, mode_t mode,
                                         struct hello_dir_entry *parent)
{
printk("create_hello_entry\n");
        struct hello_dir_entry *ent;
        nlink_t nlink;

        if (S_ISDIR(mode)) {
                if ((mode & S_IALLUGO) == 0)
                        mode |= S_IRUGO | S_IXUGO;
                nlink = 2;
        } else {
                if ((mode & S_IFMT) == 0)
                        mode |= S_IFREG;
                if ((mode & S_IALLUGO) == 0)
                        mode |= S_IRUGO;
                nlink = 1;
        }

        ent = hello_create(&parent,name,mode,nlink);
        if (ent) {
                if (hello_register(parent, ent) < 0) {
                        kfree(ent);
                        ent = NULL;
                }
        }
        return ent;
}

static inline struct hello_dir_entry *hello_read_entry(const char *name,
        mode_t mode, struct hello_dir_entry *base,
        read_hello_t *read_hello, void * data)
{
printk("hello_dir_entry\n");
        struct hello_dir_entry *res=create_hello_entry(name,mode,base);
        if (res) {
                res->;read_hello=read_hello;
                res->;write_hello = NULL;
                res->;data=data;
        }
        return res;
}

/************************************************************************************************************/
int read_hello(char *page, char **start, off_t off, int count, int *eof, void *data)
{
        strcpy(page, "hello world!");
        return 13;
}

int hello_misc_init(void)
{
printk("hello_misc_init\n");
        struct hello_dir_entry *err;
        err = hello_read_entry("zhang", 0, NULL, read_hello, NULL);
        return !err;
}                mount.c

CODE:
[Copy to clipboard]
#include "hello.h"
/*加载模块并安装文件系统*/

static DECLARE_FSTYPE(hello_fs_type, "hello", hello_read_super, FS_SINGLE);
struct vfsmount *mnt;

int hello_root_init(void)
{
        struct nameidata nd;
        int err;
        err = register_filesystem(&hello_fs_type);
printk("register_filesystem\n");
        if (err)
                return err;
        mnt = kern_mount(&hello_fs_type);/*安装文件系统*/
printk("kern_mount\n");
        err = PTR_ERR(mnt);
        if (IS_ERR(mnt))
                goto out;
        hello_misc_init();

MOD_DEC_USE_COUNT;
        char *name, *type;
        name = kmalloc(10, GFP_KERNEL);
        type = kmalloc(10, GFP_KERNEL);
        strcpy(name, "/hello");
        strcpy(type, "hello");
        long (*do_mount)(char *, char *, char *, unsigned long, void *) = (void*)0xc01603f0;/*0xc0166ad0;*/
        do_mount(NULL, name, type, 0, NULL);
        kfree(name);
        kfree(type);
        /*if (err)
                goto out;
        */

        return 0;
out:
        mntput(mnt);
        unregister_filesystem(&hello_fs_type);
        return err;
}

int init_module(void)
{
printk("init_module\n");
        hello_root_init();
        return 0;
}

void cleanup_module()
{
printk("cleanup_module\n");
        mntput(mnt);
        unregister_filesystem(&hello_fs_type);
} Makefile

CODE:
[Copy to clipboard]
CC = gcc
CFLAGS = -O -Wall -D__KERNEL__ -DMODULE
#INCLUDEDIR =  /usr/local/linux-2.4.22/include

INCLUDEDIR =  /usr/src/linux-2.4.20-8/include
CFLAGS += -I$(INCLUDEDIR)

myfs.o:                mount.o hello_entry.o hello.o
        $(LD) -m elf_i386 -r -o myfs.o mount.o hello_entry.o hello.o

mount.o:        mount.c hello.h /usr/include/linux/version.h
        $(CC) $(CFLAGS) -c mount.c
       
hello_entry.o:        hello_entry.c hello.h /usr/include/linux/version.h
        $(CC) $(CFLAGS) -c hello_entry.c
       
hello.o:        hello.c hello.h /usr/include/linux/version.h
        $(CC) $(CFLAGS) -c hello.c 测试程序read.c

CODE:
[Copy to clipboard]
#include <sys/ioctl.h>;
#include <sys/types.h>;
#include <sys/stat.h>;
#include <fcntl.h>;

int main()
{
        int fp;
        char buf[11];
        buf[10] = 0;
        int i;
       
        if ((fp = open("/hello/zhang", O_RDWR)) == 0) {
                printf("Could not opened!\n");
                return -1;
        }
        else
                printf("File open ok!\n");
        read(fp, buf, 13);
        printf("%s\n", buf);
        close(fp);
}
排行榜 更多 +
暴走吞噬免费版

暴走吞噬免费版

休闲益智 下载
滑动消方块吧最新版

滑动消方块吧最新版

休闲益智 下载
抓不到我吧手机版

抓不到我吧手机版

休闲益智 下载