Chinaunix首页 | 论坛 | 博客
  • 博客访问: 363795
  • 博文数量: 168
  • 博客积分: 6895
  • 博客等级: 准将
  • 技术积分: 1726
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-12 23:01
文章分类

全部博文(168)

文章存档

2011年(6)

2010年(162)

我的朋友

分类: LINUX

2010-11-03 22:18:19

    Today is good. Do some hacking about fs. It is so cool. That feeling i can not describe.   :)  Following is code.

    Attention: code is from  brother Wuting and Xu zhen wen.


#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include "auditfs.h"
/*
 * typedef int            __kernel_ssize_t;
 * typedef __kernel_ssize_t    ssize_t;
 * */


#define XUXFS_MAGIC 0x3966477      /* It is interesting, which called magic number. :). It used for fill superblock so that we can know its fs type*/
/*
#define XUXFS_DIR   0x0001
#define PAGE_CACHE_MASK         PAGE_MASK
#define PAGE_MASK       (~(PAGE_SIZE-1))
*/


static struct vfsmount *auditfs_mount;
static int auditfs_mount_count;

/*struct super_block * auditfs_sb = NULL;*/

static bool auditfs_registered;

static const struct super_operations sysfs_ops = {
        .statfs         = simple_statfs,   /*get fs's statistical information. Also, simple_statfs is for fs writers, which located in linux-*.*.?/fs/libfs.c. */
        .drop_inode     = generic_delete_inode,  /*release inode. generic_delete_inode is in linux-?.?.?/fs/inode.c. hack :) */
};

static ssize_t default_read_file(struct file *file, char __user *buf,
                                 size_t count, loff_t *ppos)
{
        return 0;
}

static ssize_t default_write_file(struct file *file, const char __user *buf,
                                   size_t count, loff_t *ppos)
{
        return count;
}

static int default_open(struct inode *inode, struct file *file)
{
        if (inode->i_private)
                file->private_data = inode->i_private;

        return 0;
}

const struct file_operations auditfs_file_operations = {
        .read =         default_read_file,
        .write =        default_write_file,
        .open =         default_open,
};



static struct inode *auditfs_get_inode(struct super_block *sb, int mode, dev_t dev)
{
        struct inode *inode = new_inode(sb);

        if (inode) {
                inode->i_mode = mode;
                inode->i_uid = 0;
                inode->i_gid = 0;
                inode->i_blocks = 0;
                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
                        inode->i_fop = &auditfs_file_operations;
                }
       
        return inode;
}

/**
 * d_instantiate - fill in inode information for a dentry
 * @entry: dentry to complete
 * @inode: inode to attach to this dentry
 *
 * Fill in inode information in the entry.
 *
 * This turns negative dentries into productive full members
 * of society.
 *
 * NOTE! This assumes that the inode count has been incremented
 * (or otherwise set) by the caller to indicate that it is now
 * in use by the dcache.
 */
static int auditfs_mknod(struct inode *dir, struct dentry *dentry,
                         int mode, dev_t dev)
{
        struct inode *inode;
        int error = -EPERM;    /*operations are not permitted*/

        if (dentry->d_inode)
                return -EEXIST; /*file exist*/

        inode = auditfs_get_inode(dir->i_sb, mode, dev);
        if (inode) {
                d_instantiate(dentry, inode);
                dget(dentry);
                error = 0;
        }
        return error;
}

static int auditfs_create(struct inode *dir, struct dentry *dentry, int mode)
{
        int res;

        mode = (mode & S_IALLUGO) | S_IFREG;
        res = auditfs_mknod(dir, dentry, mode, 0);
        if (!res)
                fsnotify_create(dir, dentry);
        return res;
}

static inline int auditfs_positive(struct dentry *dentry)
{
        return dentry->d_inode && !d_unhashed(dentry);
}


static int auditfs_fill_super(struct super_block *sb, void *data, int silent)
{
        static struct tree_descr auditfs_files[] = {{""}};

        return simple_fill_super(sb, XUXFS_MAGIC, auditfs_files);
}




static int audit_get_sb(struct file_system_type *fs_type,
            int flags, const char *dev_name,
            void *data, struct vfsmount *mnt)
{
    return get_sb_single(fs_type, flags, data, auditfs_fill_super, mnt);
}

static struct file_system_type audit_fs_type = {
    .owner =    THIS_MODULE,
    .name =        "auditfs",
    .get_sb =    audit_get_sb,
    .kill_sb =    kill_litter_super,
};


static int auditfs_create_by_name(const char *name, mode_t mode,
                                  struct dentry *parent,
                                  struct dentry **dentry)
{
        int error = 0;

        if (!parent) {
                if (auditfs_mount && auditfs_mount->mnt_sb) {
                        parent = auditfs_mount->mnt_sb->s_root;
                }
        }
        if (!parent) {
                return -EFAULT;
        }

        *dentry = NULL;
        *dentry = lookup_one_len(name, parent, strlen(name));
             error = auditfs_create(parent->d_inode, *dentry, mode);
                dput(*dentry);   /* dput release a dentry*/

        return error;
}



struct dentry *auditfs_create_file(const char *name, mode_t mode,
           struct dentry *parent, void *data,
                                   const struct file_operations *fops)
{
        struct dentry *dentry = NULL;
        int error;


        error = simple_pin_fs(&audit_fs_type, &auditfs_mount,
                              &auditfs_mount_count);
        if (error)
                goto exit;

        error = auditfs_create_by_name(name, mode, parent, &dentry);
        if (error) {
                dentry = NULL;
                simple_release_fs(&auditfs_mount, &auditfs_mount_count);
                goto exit;
        }

        if (dentry->d_inode) {
                if (data)
                        dentry->d_inode->i_private = data;
                if (fops)
                        dentry->d_inode->i_fop = fops;
        }
exit:
        return dentry;
}
EXPORT_SYMBOL_GPL(auditfs_create_file);
struct dentry *auditfs_create_dir(const char *name, struct dentry *parent)
{
        return auditfs_create_file(name,
                                   S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
                                   parent, NULL, NULL);
}
EXPORT_SYMBOL_GPL(auditfs_create_dir);  /*export the symbol so that other moudules can use the function*/


static int __init auditfs_init(void)   /*init the file system, in fact, it is important :) */
{

    int retval;


    retval = register_filesystem(&audit_fs_type);
       if (!retval) {
                auditfs_mount = vfs_kern_mount(&audit_fs_type,MS_KERNMOUNT,(&audit_fs_type)->name,NULL);/*MS_KERNMOUNT is a kernel_mount call*/
                if (IS_ERR(auditfs_mount)) {
                        printk(KERN_ERR "auditfs: could not mount!\n");
                        retval= PTR_ERR(auditfs_mount);
                        auditfs_mount = NULL;
                        unregister_filesystem(&audit_fs_type);
                        return retval;
                }
    }
    return 0;
}

static void __exit auditfs_exit(void)   /*exit the file system*/
{
    auditfs_registered = false;

    simple_release_fs(&auditfs_mount, &auditfs_mount_count);
    unregister_filesystem(&audit_fs_type);   /*Zero is okay, or failure*/
}

module_init(auditfs_init);   /*the kernel module things*/
module_exit(auditfs_exit);
MODULE_LICENSE("GPL");




Any question can communicate with me, thanks.
  Bye  :)
阅读(423) | 评论(1) | 转发(0) |
0

上一篇:10 31

下一篇:11 4

给主人留下些什么吧!~~

chinaunix网友2010-11-05 08:52:14

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com