当前位置:操作系统 > Unix/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
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,