当前位置导航:炫浪网>>网络学院>>操作系统>>Linux教程

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


  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) < 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*/
  };
  
  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
相关内容
赞助商链接