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

📄 super.c

📁 mtd最新cvs的ffs系统
💻 C
📖 第 1 页 / 共 4 页
字号:
      }      // Erase it      if (top != oldloc)	 free_alloc(r,oldloc);      else      {	 // The first entry we set to deleted and do not erase	 __u8 status = entry->Status;	 status = status & (~FFS_ENTRY_EXISTS);	 if (ffs2_write(r,block,offset,&status,sizeof(status)) != 0)	    return -EIO;      }         }   return 0;}									/*}}}*/// ffs2_read_super - Read the superblock (mount)			/*{{{*/// ---------------------------------------------------------------------/* The process for locating the super block involves looking at every block   in the filesystem for a block record that has a valid boot record pointer,   following that pointer and then verifying that it is the boot block. */static struct super_block *ffs2_read_super(struct super_block *s,					   void *data,int silent){   struct ffs2_sb_info *sb;   struct ffs_read r;   unsigned long blocks;      MOD_INC_USE_COUNT;   // Setup the super block   lock_super(s);   set_blocksize(s->s_dev, BLOCK_SIZE);   s->s_blocksize = BLOCK_SIZE;   s->s_blocksize_bits = BLOCK_SIZE_BITS;   sb = &getFFS2_sb(s);   memset(sb,0,sizeof(*sb));   sb->EraseSize = 0x20000;        // Temp      memset(&r,0,sizeof(r));   r.super = s;   // Allocate the block mapping structure   blocks = blk_size[MAJOR(s->s_dev)][MINOR(s->s_dev)]*BLOCK_SIZE/sb->EraseSize;   sb->BlockMap = kmalloc(sizeof(*sb->BlockMap)*blocks,GFP_KERNEL);   if (sb->BlockMap == 0)   {      s->s_dev = 0;      unlock_super(s);      MOD_DEC_USE_COUNT;      return 0;         }   memset(sb->BlockMap,0xFF,sizeof(*sb->BlockMap)*blocks);      /* Perform the filesystem startup, locate the boot block, do      a cleanup, etc. */   if (ffs2_find_boot_block(&r,blocks) != 0 || ffs2_prepare(&r) != 0 ||        ffs2_prepare_info(&r))   {      printk("ffs2: Could not find the superblock\n");      kfree(sb->BlockMap);      ffs2_relse(&r);      s->s_dev = 0;      unlock_super(s);      MOD_DEC_USE_COUNT;      return 0;         }   ffs2_relse(&r);      s->s_op = &ffs2_ops;   s->s_root = d_alloc_root(iget(s,sb->Boot.RootDirectoryPtr),NULL);      unlock_super(s);      return s;}									/*}}}*/// ffs2_put_super - Put back the superblock (unmount)			/*{{{*/// ---------------------------------------------------------------------/* Not much to do here..*/static void ffs2_put_super(struct super_block *s){   unsigned I;      kfree(getFFS2_sb(s).BlockMap);      for (I = 0; I != getFFS2_sb(s).Boot.TotalBlockCount; I++)      kfree(getFFS2_sb(s).Blocks[I].FreeList);   kfree(getFFS2_sb(s).Blocks);      MOD_DEC_USE_COUNT;   return;}									/*}}}*/// ffs2_statfs - Stat the filesystem get free blocks, etc		/*{{{*/// ---------------------------------------------------------------------/* */static int ffs2_statfs(struct super_block *s, struct statfs *buf, int bufsize){   struct statfs tmp;   struct ffs2_sb_info *sb = &getFFS2_sb(s);   unsigned int I;      memset(&tmp, 0, sizeof(tmp));   tmp.f_type = FFS2_MAGIC;   tmp.f_bsize = 1;   tmp.f_blocks = sb->Boot.TotalBlockCount - sb->Boot.SpareBlockCount;   tmp.f_blocks *= sb->Boot.BlockLen;   tmp.f_namelen = FFS2_MAXFN;      // Count up free space   for (I = 0; I != sb->Boot.TotalBlockCount; I++)   {      tmp.f_bfree += sb->Blocks[I].FreeSpace  +	 sb->Blocks[I].ReclaimableSpace;   }   tmp.f_bavail = tmp.f_bfree;         return copy_to_user(buf, &tmp, bufsize) ? -EFAULT : 0;}									/*}}}*/// ffs2_readdir - Read a list of files from a directory			/*{{{*/// ---------------------------------------------------------------------/* read a directory. offset is the number of extents into the directory,   I am not sure exactly how the calling code uses this, but it would be   more effecient to store a pointer to the current entry in offset, but    that is basically a random value.. */static int ffs2_readdir(struct file *filp, void *dirent, filldir_t filldir){   struct ffs2_entry *entry;   struct inode *i = filp->f_dentry->d_inode;   struct ffs_read r;   unsigned int stored = 0;   unsigned int offset = 1;   unsigned long cur;      memset(&r,0,sizeof(r));      r.super = i->i_sb;      // Locate the inode   entry = ffs2_find_entry(&r,i->i_ino);   if (entry == 0)   {      ffs2_relse(&r);      return 0;   }   if (offset > filp->f_pos)   {      filp->f_pos = offset;      if (filldir(dirent,".",1,filp->f_pos,i->i_ino) < 0)      {	 ffs2_relse(&r);	 return stored;      }      stored++;   }   offset++;          if (offset > filp->f_pos)   {      unsigned long node = 0;      if (i->i_ino == getFFS2_sb(i->i_sb).Boot.RootDirectoryPtr)	 node = i->i_ino;            filp->f_pos = offset;      if (filldir(dirent,"..",2,filp->f_pos,node) < 0)      {	 ffs2_relse(&r);	 return stored;      }      stored++;   }   offset++;      // Iterate over all of the extents for the directory   if (!isFNULL(entry->PrimaryPtr) &&       (entry->Status & FFS_ENTRY_PRIMARY) != FFS_ENTRY_PRIMARY)   {      cur = entry->PrimaryPtr;      while (1)      {	 struct ffs2_entry *extent = ffs2_find_entry(&r,cur);	 if (extent == 0)	 {	    printk("ffs2: Failure reading directory component\n");	    break;	 }	 // This should not happen.	 if (isflagset(extent->Status,FFS_ENTRY_TYPEMASK,FFS_ENTRY_TYPEEXTENT))	 {	    printk("ffs2: Filesystem corruption, an extent in the directory list\n");	    break;	 }	 	    	 // Fill in the dirent structure	 if ((extent->Status & FFS_ENTRY_EXISTS) == FFS_ENTRY_EXISTS)	 {	    if (offset > filp->f_pos)	    {	       char S[100];	       strncpy(S,extent->Name,extent->NameLen);	       S[extent->NameLen] = 0;	       filp->f_pos = offset;	       if (filldir(dirent,extent->Name,extent->NameLen,filp->f_pos,cur) < 0)		  break;	       stored++;	    }	    	    offset++;	 }	 	 // 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);      return stored;}									/*}}}*/// ffs2_lookup - Lookup a file in a directory by name			/*{{{*/// ---------------------------------------------------------------------/* This is the same as ffs2_readdir, but doesnt do adds, just compares */static struct dentry *ffs2_lookup(struct inode *dir, struct dentry *dentry){   struct inode *inode;   struct ffs_read r;   unsigned long pos;   int res;      memset(&r,0,sizeof(r));      r.super = dir->i_sb;      res = ffs2_find_dirent(&r,dir->i_ino,&dentry->d_name,&pos);   if (res != 0)   {      ffs2_relse(&r);      if (res == -1)      {	 d_add(dentry,0);	 return ERR_PTR(0);      }            return ERR_PTR(-EIO);   }   ffs2_relse(&r);      if ((inode = iget(dir->i_sb,pos)) == NULL)      return ERR_PTR(-EACCES);   d_add(dentry, inode);   return 0;}									/*}}}*/// ffs2_readpage - Read a page from the file				/*{{{*/// ---------------------------------------------------------------------/* This is the 'read' function, it works in PAGE_SIZE blocks, reading    from the file system directly into the page. It is forced to iterate over   many of the extent headers which will slow things down.. */static int ffs2_readpage(struct file *file, struct page *page){   struct dentry *dentry = file->f_dentry;   struct inode *inode = dentry->d_inode;   unsigned char *buf;   unsigned long offset, avail, readlen;   int result = -EIO;   struct ffs2_entry *entry;   struct ffs_read r;   unsigned long cur;      memset(&r,0,sizeof(r));      r.super = inode->i_sb;      // Setup the page   atomic_inc(&page->count);   set_bit(PG_locked, &page->flags);   buf = (unsigned char *)page_address(page);   clear_bit(PG_uptodate, &page->flags);   clear_bit(PG_error, &page->flags);      // Past then end is == 0   readlen = 1;   while (page->offset < inode->i_size)    {      avail = inode->i_size - page->offset;      readlen = PAGE_SIZE;      if (avail < readlen)	 readlen = avail;      // Blank out the end of the page      if (readlen < PAGE_SIZE) 	 memset(buf + readlen,0,PAGE_SIZE-readlen);      // 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)	 break;            // Check for compression      if ((entry->Status >> FFS_ENTRY_COMPIP_SHIFT) != 0xFF)      {	 printk("ffs2: No support for compressed format %x\n",		entry->Status >> FFS_ENTRY_COMPIP_SHIFT);	 break;      }                  cur = entry->PrimaryPtr;      offset = 0;      while (readlen > 0)      {	 unsigned long length = 0;	 	 struct ffs2_fileinfo *extent = (struct ffs2_fileinfo *)ffs2_find_entry(&r,cur);	 if (extent == 0)	    break;	 	 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	 length = extent->UncompressedExtentLen;	 if (offset + extent->UncompressedExtentLen > page->offset)	 {	    unsigned long toread = extent->UncompressedExtentLen;	    int res;	    if (toread > readlen)	       toread = readlen;	    	    if (page->offset >= offset)	       res = ffs2_copy_to_buff(&r,buf,extent,toread,page->offset - offset);	    else	       res = ffs2_copy_to_buff(&r,buf + offset - page->offset,extent,toread,0);	    if (res != 0)	       break;	    readlen -= toread;	 }	 if (length == 0)	    break;	 	 offset += length;	 if (cur == 0xFFFFFFFF)	    break;      }            break;   }      ffs2_relse(&r);   if (readlen == 0)   {      set_bit(PG_uptodate, &page->flags);      result = 0;   }         else   {            set_bit(PG_error, &page->flags);      memset((void *)buf, 0, PAGE_SIZE);   }         clear_bit(PG_locked, &page->flags);   wake_up(&page->wait);   free_page((unsigned long)buf);      return result;}									/*}}}*/// ffs2_readlink - Read a symlink					/*{{{*/// ---------------------------------------------------------------------/* */static int ffs2_readlink(struct dentry *dentry, char *buffer, int len){   printk("readlink\n");   return -EIO;   }									/*}}}*/// ffs2_follow_link - ??						/*{{{*/// ---------------------------------------------------------------------/* */static struct dentry *ffs2_follow_link(struct dentry *dentry,					struct dentry *base,					unsigned int follow){   printk("followlink\n");   return ERR_PTR(EAGAIN);}									/*}}}*/// ffs2_read_inode - Fill in an inode					/*{{{*/// ---------------------------------------------------------------------/* This function fills in the information for an inode. For FFS an inode   is defined to be the DirEntry/FileEntry for the object in question. The   inode number is the pointer this structure. */static void ffs2_read_inode(struct inode *i){   struct ffs2_entry *entry;   struct ffs_read r;   unsigned long cur;      memset(&r,0,sizeof(r));      r.super = i->i_sb;   // Setup the super block   //lock_super(i->i_sb);   // Locate the real inode   entry = ffs2_find_entry(&r,i->i_ino);   if (entry == 0)   {      ffs2_relse(&r);      return;   }      i->i_mode = 0;   i->i_nlink = 1;    // FFS does not have a link concept   i->i_size = 0;   i->i_mtime = i->i_atime = i->i_ctime = 0;   i->i_uid = i->i_gid = 0;   i->i_op = ffs2_inoops[1];      // Decide on the mode   if (isflagset(entry->Status,FFS_ENTRY_TYPEMASK,FFS_ENTRY_TYPEDIR))   {      i->i_op = ffs2_inoops[1];      i->i_mode = S_IRWXUGO | S_IFDIR;   }   else   {      i->i_op = ffs2_inoops[2];      // i->i_mode = (S_IRWXUGO & (~S_IXUGO)) | S_IFREG;      i->i_mode = S_IRWXUGO | S_IFREG;   }      // Compute the size and locate the date/time   if (!isFNULL(entry->PrimaryPtr) &&       (entry->Status & FFS_ENTRY_PRIMARY) != FFS_ENTRY_PRIMARY)   {      cur = entry->PrimaryPtr;      while (1)      {	 struct ffs2_entry *extent = ffs2_find_entry(&r,cur);	 if (extent == 0)	 {	    ffs2_relse(&r);	    return;

⌨️ 快捷键说明

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