⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 super.c

📁 mtd最新cvs的ffs系统
💻 C
📖 第 1 页 / 共 4 页
字号:
	 }	 	 /* Grab the correct time. Technically the spec says this should use	    the stupid DOS format, but QNX's File System stores a sensible	    unix date in here, so we use that instead. Maybe make this an	    option, the fat code in linux has the decoding routines. */	 if ((extent->Status & FFS_ENTRY_TIME) == FFS_ENTRY_TIME)	    i->i_mtime = i->i_atime = i->i_ctime = extent->Time + (extent->Date << 16);	 /* Add in the size and step to the next entry. For some crazed	    reason the meanings of primary+sibling swap for entries :< */	 if (isflagset(extent->Status,FFS_ENTRY_TYPEMASK,FFS_ENTRY_TYPEEXTENT))	 {	    i->i_size += ((struct ffs2_fileinfo *)extent)->UncompressedExtentLen;	    // Skip to the next one	    if (isFNULL(extent->PrimaryPtr) == 0 &&		(extent->Status & FFS_ENTRY_PRIMARY) != FFS_ENTRY_PRIMARY)	       cur = extent->PrimaryPtr;	    else	       break;	 }	 	 else	 {	    i->i_size += sizeof(*extent) + extent->NameLen;	 	    // Skip to the next one	    if (isFNULL(extent->SiblingPtr) == 0 &&		(extent->Status & FFS_ENTRY_SIBLING) != FFS_ENTRY_SIBLING)	       cur = extent->SiblingPtr;	    else	       break;	 }	       }   }      ffs2_relse(&r);}									/*}}}*/// ffs2_mkdir - Make a new directory					/*{{{*/// ---------------------------------------------------------------------/* */static int ffs2_mkdir(struct inode *dir, struct dentry *dentry, int mode){   return ffs2_new_entry(dir,dentry,&dentry->d_name,FFS_ENTRY_TYPEDIR);}									/*}}}*/// ffs2_create - Create a new file					/*{{{*/// ---------------------------------------------------------------------/* */static int ffs2_create(struct inode *dir,struct dentry *dentry,int mode){   return ffs2_new_entry(dir,dentry,&dentry->d_name,FFS_ENTRY_TYPEFILE);}									/*}}}*/// ffs2_unlink - Unlink a file						/*{{{*/// ---------------------------------------------------------------------/* This does a very unsafe unlink operation. It goes over the linked list   of extents and marks them all as erased. If this routine is interrupted   the filesystem will have unreclaimable blocks but will still be    consistent */static int ffs2_unlink(struct inode *dir,struct dentry *dentry){   struct ffs_read r;   struct ffs2_entry *entry;   struct ffs2_blockalloc alloc;   unsigned long loc;   int res;      memset(&r,0,sizeof(r));      r.super = dir->i_sb;      // Locate the entry in the directory   res = ffs2_find_dirent(&r,dir->i_ino,&dentry->d_name,&loc);   if (res != 0 || ffs2_find_blockalloc(&r,loc,&alloc) != 0)   {      ffs2_relse(&r);      if (res == -1)	 return -ENOENT;      return -EIO;   }   entry = (struct ffs2_entry *)r.p;      // Dont unlink directories, use rmdir for that   if (isflagset(entry->Status,FFS_ENTRY_TYPEMASK,FFS_ENTRY_TYPEDIR))   {      ffs2_relse(&r);      return -EISDIR;   }   if (ffs2_erase(&r,loc,0) != 0)   {      ffs2_relse(&r);      return -EIO;   }      ffs2_relse(&r);   return 0;}									/*}}}*/// ffs2_rmdir - Remove a directory					/*{{{*/// ---------------------------------------------------------------------/* This is similar to ffs2_unlink, except that it checks to make sure the   directory is empty before trying to erase */static int ffs2_rmdir(struct inode *dir,struct dentry *dentry){   struct ffs_read r;   struct ffs2_entry *entry;   unsigned long loc;   unsigned long jnk;   int res;      memset(&r,0,sizeof(r));      r.super = dir->i_sb;      // Locate the entry in the directory   res = ffs2_find_dirent(&r,dir->i_ino,&dentry->d_name,&loc);   if (res != 0 || ffs2_find_blockalloc(&r,loc,0) != 0)   {      ffs2_relse(&r);      if (res == -1)	 return -ENOENT;      return -EIO;   }   entry = (struct ffs2_entry *)r.p;   // Dont unlink a file, use rmdir for that   if (!isflagset(entry->Status,FFS_ENTRY_TYPEMASK,FFS_ENTRY_TYPEDIR))   {      ffs2_relse(&r);      return -ENOTDIR;   }   // Check for emptyness   if (ffs2_find_dirent(&r,loc,0,&jnk) == 0)   {      ffs2_relse(&r);      return -ENOTEMPTY;   }      if (ffs2_erase(&r,loc,1) != 0)   {      ffs2_relse(&r);      return -EIO;   }		        ffs2_relse(&r);   return 0;}									/*}}}*/// ffs2_rename - Rename a file 						/*{{{*/// ---------------------------------------------------------------------/* */static int ffs2_rename(struct inode *old_dir, struct dentry *old_dentry,		       struct inode *new_dir, struct dentry *new_dentry){   return -ENOENT;}									/*}}}*/// ffs2_file_write - Write a file					/*{{{*/// ---------------------------------------------------------------------/* */static ssize_t ffs2_file_write(struct file *filp,const char *buf,			       size_t count,loff_t *ppos){   struct inode *inode = filp->f_dentry->d_inode;   off_t pos;   ssize_t written;   char *tmp;   struct ffs2_entry *entry;   struct ffs_read r;   unsigned long cur;   unsigned long offset;   ssize_t res = 0;      memset(&r,0,sizeof(r));      r.super = inode->i_sb;   // Make sure the inode is sensible   if (!inode || !S_ISREG(inode->i_mode))      return -EINVAL;   // Get the writing position   if (filp->f_flags & O_APPEND)      pos = inode->i_size;   else      pos = *ppos;   written = 0;   // Get the inode and follow to find the first extent   if ((entry = ffs2_find_entry(&r,inode->i_ino)) == 0 ||       isFNULL(entry->PrimaryPtr) ||       (entry->Status & FFS_ENTRY_PRIMARY) == FFS_ENTRY_PRIMARY)   {      cur = inode->i_ino;   }   else   {      cur = entry->PrimaryPtr;   }      // Check for compression (this isnt quite right..)   if ((entry->Status >> FFS_ENTRY_COMPIP_SHIFT) != 0xFF)   {      printk("ffs2: No support for compressed foramt %x\n",	     entry->Status >> FFS_ENTRY_COMPIP_SHIFT);      ffs2_relse(&r);      return -EINVAL;   }      /* Search for the first block that overlaps this block, or the end of      the list */   offset = 0;   written = 0;   tmp = kmalloc(PAGE_SIZE,GFP_KERNEL);   while (written < count)   {      unsigned long oldcur = cur;      struct ffs2_fileinfo *extent = (struct ffs2_fileinfo *)ffs2_find_entry(&r,cur);      if (extent == 0)	 break;      // This is invoked if there is no extents at all      if (cur != inode->i_ino)      {	 if (!isflagset(extent->Status,FFS_ENTRY_TYPEMASK,FFS_ENTRY_TYPEEXTENT))	    break;	 	 // Skip cur to the next one	 if (isFNULL(extent->PrimaryPtr) == 0 &&	     (extent->Status & FFS_ENTRY_PRIMARY) != FFS_ENTRY_PRIMARY)	    cur = extent->PrimaryPtr;	 else	    cur = 0xFFFFFFFF;	 	 if ((extent->Status & FFS_ENTRY_EXISTS) != FFS_ENTRY_EXISTS)	    continue;	 	 // See if we have entered the copy region	 if (offset + extent->UncompressedExtentLen > pos)	 {	    printk("ffs2: No support for overwriting\n");	    res = -EINVAL;	    break;	 }	       }      else	 cur = 0xFFFFFFFF;            // Check if the end of this block is the start of the insertion region      if (cur == 0xFFFFFFFF && offset + extent->UncompressedExtentLen >= pos)      {	 	 /* Allocate a new block, write the data and link it to the 	    last block, repeatedly growing the length of the chain */	 while (written < count)	 {	    unsigned long ext;	    ssize_t c = count - written;	    if (c > PAGE_SIZE)	       c = PAGE_SIZE;	    if (copy_from_user(tmp,buf,c) != 0)	    {	       res = -EFAULT;	       break;	    }	    	    written += c;	    if (ffs2_new_extent(&r,tmp,c,&ext) != 0)	    {	       res = -EIO;	       break;	    }	    	    res = update_pointer(&r,oldcur,ext,FFS_PTR_PRIMARY);	    if (res != 0)	       break;	    	    update_vm_cache(inode,pos,tmp,c);	    oldcur = ext;	    pos += c;	    offset += c;	 }	 break;      }            offset += ((struct ffs2_fileinfo *)extent)->UncompressedExtentLen;      if (cur == 0xFFFFFFFF)      {	 printk("ffs2: Sparse files not supported\n");	 res = -EINVAL;	 break;      }         }      kfree(tmp);   ffs2_relse(&r);      if (res != 0)      return res;   *ppos = pos;   if (pos > inode->i_size)      inode->i_size = pos;      return written;}									/*}}}*/// Kernel Binding							/*{{{*/static struct file_operations ffs2_file_operations ={   NULL,			/* lseek - default */   generic_file_read,		/* read */   ffs2_file_write,		/* write */   NULL,			/* readdir */   NULL,			/* poll - default */   NULL,			/* ioctl */   generic_file_mmap,		/* mmap */   NULL,			/* open */   NULL,			/* flush */   NULL,			/* release */   NULL,			/* fsync */   NULL,			/* fasync */   NULL,			/* check_media_change */   NULL				/* revalidate */};static struct inode_operations ffs2_file_inode_operations ={   &ffs2_file_operations,   NULL,			/* create */   NULL,			/* lookup */   NULL,			/* link */   NULL,			/* unlink */   NULL,			/* symlink */   NULL,			/* mkdir */   NULL,			/* rmdir */   NULL,			/* mknod */   NULL,			/* rename */   NULL,			/* readlink */   NULL,			/* follow_link */   ffs2_readpage,		/* readpage */   NULL,			/* writepage */   NULL,			/* bmap -- not really */   NULL,			/* truncate */   NULL,			/* permission */   NULL,			/* smap */};static struct file_operations ffs2_dir_operations ={   NULL,			/* lseek - default */   NULL,			/* read */   NULL,			/* write - bad */   ffs2_readdir,		/* readdir */   NULL,			/* poll - default */   NULL,			/* ioctl */   NULL,			/* mmap */   NULL,			/* open */   NULL,			/* flush */   NULL,			/* release */   NULL,			/* fsync */   NULL,			/* fasync */   NULL,			/* check_media_change */   NULL				/* revalidate */};static struct inode_operations ffs2_dir_inode_operations ={   &ffs2_dir_operations,   ffs2_create,			/* create */   ffs2_lookup,			/* lookup */   NULL,			/* link */   ffs2_unlink,			/* unlink */   NULL,			/* symlink */   ffs2_mkdir,			/* mkdir */   ffs2_rmdir,			/* rmdir */   NULL,			/* mknod */   ffs2_rename,			/* rename */   NULL,			/* readlink */   NULL,			/* follow_link */   NULL,			/* readpage */   NULL,			/* writepage */   NULL,			/* bmap */   NULL,			/* truncate */   NULL,			/* permission */   NULL,			/* smap */};static struct inode_operations ffs2_link_inode_operations ={   NULL,			/* no file operations on symlinks */   NULL,			/* create */   NULL,			/* lookup */   NULL,			/* link */   NULL,			/* unlink */   NULL,			/* symlink */   NULL,			/* mkdir */   NULL,			/* rmdir */   NULL,			/* mknod */   NULL,			/* rename */   ffs2_readlink,		/* readlink */   ffs2_follow_link,		/* follow_link */   NULL,			/* readpage */   NULL,			/* writepage */   NULL,			/* bmap */   NULL,			/* truncate */   NULL,			/* permission */   NULL,			/* smap */};static struct inode_operations *ffs2_inoops[] ={   NULL,			/* hardlink, handled elsewhere */   &ffs2_dir_inode_operations,   &ffs2_file_inode_operations,   &ffs2_link_inode_operations,   &blkdev_inode_operations,	/* standard handlers */   &chrdev_inode_operations,   NULL,			/* socket */   NULL,			/* fifo */};static struct super_operations ffs2_ops ={   ffs2_read_inode,		/* read inode */   NULL,			/* write inode */   NULL,			/* put inode */   NULL,			/* delete inode */   NULL,			/* notify change */   ffs2_put_super,		/* put super */   NULL,			/* write super */   ffs2_statfs,		/* statfs */   NULL				/* remount */};static struct file_system_type ffs2_fs_type ={   "ffs2",   FS_REQUIRES_DEV,   ffs2_read_super,   NULL};									/*}}}*/// Init Stuff								/*{{{*/int __init init_ffs2_fs(){   return register_filesystem(&ffs2_fs_type);}#ifdef MODULEEXPORT_NO_SYMBOLS;int init_module(void){   return init_ffs2_fs();}void cleanup_module(){   unregister_filesystem(&ffs2_fs_type);}#endif									/*}}}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -