亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? super.c

?? mtd最新cvs的ffs系統(tǒng)
?? C
?? 第 1 頁 / 共 4 頁
字號:
// -*- mode: cpp; mode: fold -*-// Description                                                          /*{{{*/// $Id: super.c,v 1.1 2000/03/27 07:14:15 dwmw2 Exp $/* ######################################################################   Microsoft Flash File System 2       Information for the FFS2.0 was found in Microsoft's knowledge base,   http://msdn.microsoft.com/isapi/msdnlib.idc?theURL=/library/specs/S346A.HTM   Try searching for "Flash File System" if it has been moved      The filesystem can run in two modes, directly on a MTD or indirectly   through the block system. The FFS2 filesystem was really designed for    linearly mapped flash, it has no block alignment aside from the   erase unit size which makes it difficult to fit into the block    device model.   While operating the filesystem runs in such a way that a crash will not   damage the consistency of the filesystem. All crashes will result in    allocated but unreferenced blocks that can be easially reclaimed by   probing the entire allocation tree. There is a risk that a file entry    pointer could be partialy written to. In this case that entry pointer is   useless - the simplest way out is to reclaim that block and set the    pointer back to FF. There is, unfortunately, no really good mechanism to   do that directly :<      TODO:     - Byte swapping (Carefull, the structures are returned directly from       bh's!)     - Compression check should be equal sizes not by compress ID     - Write routine needs to handle more cases, particularly overwriting,       not just append     - Directory additions should check and reclaim very long directories       that are mostly empty by using superceeds     - Use a constant inode scheme like the latest FAT driver does (2.2.11)     - Rename     - Block reclimation     - Built in fsck on load - search for unreferenced blocks     - Look at extensions to handle symlinks, device nodes and ownership.       Can be done using the extension mechanism that is built in quite        directly.     - Setting the new mtimes isn't right, it needs to go back over the list       and reset the mtime valid flags. Mtime on empty newly created things       is wrong too, it needs to use the value of the item itself.     - Get support for QNX's BPE decompressor.     - Split this foolish thing up into smaller modules     - unlink seems to not flush the dentry cache?      ##################################################################### */									/*}}} */#include <linux/fs.h>#include <linux/module.h>#include <linux/types.h>#include <linux/errno.h>#include <linux/malloc.h>#include <linux/locks.h>#include <linux/init.h>#include <linux/blkdev.h>#include "ffs2_fs.h"#include "ffs2_fs_sb.h"#include "ffs2_fs_i.h"#include "local.h"#include "io.h"#include <asm/uaccess.h>static struct super_operations ffs2_ops;static struct inode_operations *ffs2_inoops[];// ffs2_getbh - Get a bh, consulting our cache first			/*{{{*/// ---------------------------------------------------------------------/* Because of the random jumps in operations like reading a directory we   keep a small cache of 4 most recent requests. This prevents BH trashing   when we lookup block allocation then block then the next allocation   etc. The speed gain on block devices is substantial. */static struct buffer_head *ffs2_getbh(struct ffs_read *r,unsigned long loc){   unsigned int I;   unsigned int old = 0;   unsigned int age = r->curage;      // Search   for (I = 0; I != sizeof(r->bh)/sizeof(*r->bh); I++)   {      if (r->bh[I] == 0)	 continue;            if (r->bh[I]->b_blocknr == loc)	 break;      if (age > r->age[I])      {	 old = I;	 age = r->age[I];      }	    }         // Miss   if (I >= sizeof(r->bh)/sizeof(*r->bh))   {      I = old;            // Free the old bh      if (r->bh[I] != 0)	 brelse(r->bh[I]);      if ((r->bh[I] = bread(r->super->s_dev,loc,BLOCK_SIZE)) == NULL)	 return 0;   }         r->age[I] = r->curage++;   return r->bh[I];}									/*}}}*/// ffs2_read - Perform a read operation					/*{{{*/// ---------------------------------------------------------------------/* This performs a read operation with no alignment constraints. If it is    possible to return the entire requested block in someone elses memory   (a MTD window or a buffer head) then that will be done, otherwise a   copy is performed to the given temporary memory and that is returned   instead. This will automatically free the ffs_read structure as it   executes. Count must be a small number, below 128. Using the    ahead/behind values it is possible to make multiple requests to    do reading */unsigned char *ffs2_read(struct ffs_read *r,unsigned long block,			 unsigned long offset,unsigned long count){   unsigned long loc;   unsigned long left;   unsigned char *pos;   if (getFFS2_sb(r->super).Boot.TotalBlockCount != 0 &&       block >= getFFS2_sb(r->super).Boot.TotalBlockCount)      return 0;   r->block = block;   r->offset = offset;   block += getFFS2_sb(r->super).ZeroBlock;   loc = getFFS2_sb(r->super).EraseSize*block + offset;   // We can return a bh..   if ((loc >> BLOCK_SIZE_BITS) == ((loc + count - 1) >> BLOCK_SIZE_BITS))   {      struct buffer_head *bh = ffs2_getbh(r,loc >> BLOCK_SIZE_BITS);      if (bh == 0)	 return 0;            r->behind = loc & (BLOCK_SIZE-1);      r->ahead = BLOCK_SIZE - r->behind;      r->p = bh->b_data + r->behind;      return r->p;   }      // Doomed :>   if (count > sizeof(r->temp))   {      printk("ffs2: Reading too much");      return 0;   }      // Need to use the temp buffer   pos = r->temp;   memset(r->temp,0,sizeof(r->temp));   left = count;   while (left != 0)   {      unsigned long behind;      unsigned long ahead;      struct buffer_head *bh = ffs2_getbh(r,loc >> BLOCK_SIZE_BITS);      if (bh == 0)	 return 0;            behind = loc & (BLOCK_SIZE-1);      ahead = BLOCK_SIZE - behind;      if (left < ahead)	 ahead = left;      memcpy(pos,bh->b_data + behind,ahead);      pos += ahead;      loc += ahead;      left -= ahead;   }   r->behind = 0;   r->ahead = count;   r->p = r->temp;   return r->p;}									/*}}}*/// ffs2_relse - Release the read structure				/*{{{*/// ---------------------------------------------------------------------/* This releases any cached BHs, it is important to call it! */void ffs2_relse(struct ffs_read *r){   unsigned I;   for (I = 0; I != sizeof(r->bh)/sizeof(*r->bh); I++)   {      if (r->bh[I] != 0)	 brelse(r->bh[I]);   }   memset(r,0,sizeof(*r));}									/*}}}*/// ffs2_write - Write data to the flash					/*{{{*/// ---------------------------------------------------------------------/* Copy the given data into the buffer cache */int ffs2_write(struct ffs_read *r,unsigned long block,	       unsigned long offset,unsigned char *from,unsigned long count){   unsigned long loc;   unsigned long left;   if (getFFS2_sb(r->super).Boot.TotalBlockCount != 0 &&       block >= getFFS2_sb(r->super).Boot.TotalBlockCount)      return 0;   r->block = block;   r->offset = offset;   block += getFFS2_sb(r->super).ZeroBlock;   loc = getFFS2_sb(r->super).EraseSize*block + offset;   /* Copy over the new data, this should probably use a mechansim that      doesnt read in the old contents if the write buffer is the full       length */   left = count;   while (left != 0)   {      unsigned long behind;      unsigned long ahead;      struct buffer_head *bh = ffs2_getbh(r,loc >> BLOCK_SIZE_BITS);      if (bh == 0)	 return -1;            /*printk("Writing %lu to %lu\n",left,loc);      {	 unsigned long I;	 for (I = 0; I < left; I++)	    printk("%x ",from[I]);	 printk("\n");      }*/            behind = loc & (BLOCK_SIZE-1);      ahead = BLOCK_SIZE - behind;      if (left < ahead)	 ahead = left;      memcpy(bh->b_data + behind,from,ahead);      from += ahead;      loc += ahead;      left -= ahead;      // Dirty the buffer      mark_buffer_uptodate(bh, 1);      mark_buffer_dirty(bh,0);   }   r->behind = 0;   r->ahead = 0;   r->p = 0;   return 0;}									/*}}}*/// insert_region - Add a new region to the list of regions		/*{{{*/// ---------------------------------------------------------------------/* The purpose here is to take a region and add it to our sorted list of   regions and merge it with the other regions in the list. */static int insert_region(struct ffs2_free_space *spaces,unsigned int max,			 unsigned long start,unsigned long len){   unsigned int I;   unsigned long end = start + len;   for (I = 0; I < max-2; I++)   {      // Merge it with the last one      if (spaces[I].Stop == start && spaces[I].Stop != 0)      {	 spaces[I].Stop = end;	 	 // Join with the next one too	 if (end == spaces[I+1].Start)	 {	    spaces[I].Stop = spaces[I+1].Stop;	    memmove(spaces + I+1,spaces + I+2,(max - I - 1)*sizeof(*spaces));	 }	 	 return 0;      }            // Merge it with the next one      if (spaces[I].Start == end)      {	 spaces[I].Start = start;	 return 0;      }      	       // Insert a new one      if (spaces[I].Start > start || spaces[I].Stop == 0)      {	 	 memmove(spaces + I+1,spaces + I,(max - I - 1)*sizeof(*spaces));	 spaces[I].Start = start;	 spaces[I].Stop = end;	 return 0;      }   }         printk("ffs2: Unable to sort allocation list");   return -1;}									/*}}}*/// ffs2_make_free_list - Generate the list of free regions		/*{{{*/// ---------------------------------------------------------------------/* This scans the block allocations and builds up a list of the free    regions. Due to the allocation model used this list should be    -short- but it is expensive to calculate the first time. */static int ffs2_make_free_list(struct ffs_read *r,unsigned block){   enum {max = 100};   struct ffs2_sb_info *sb = &getFFS2_sb(r->super);   struct ffs2_free_space spaces[max];   struct ffs2_blockalloc *alloc;   struct ffs2_sb_block *info = &sb->Blocks[block];   unsigned long cur;   unsigned long offset;      memset(spaces,0,sizeof(spaces));      // Record the end block   if (insert_region(spaces,max, sb->EraseSize - FFS_SIZEOF_BLOCK,		     FFS_SIZEOF_BLOCK) != 0)      return -1;   info->ReclaimableSpace = 0;   for (cur = 0; ; cur++)   {	        offset = sb->EraseSize - FFS_SIZEOF_BLOCK - 	       (cur + 1)*FFS_SIZEOF_BLOCKALLOC;      if (offset <= 100)      {	 printk("ffs2: Allocation list too long");	 return -1;      }            // XX can be advoided      if (ffs2_read(r,block,offset,FFS_SIZEOF_BLOCKALLOC) == 0)	 return -1;      alloc = (struct ffs2_blockalloc *)r->p;      // Record the block alloc structure      if (insert_region(spaces,max,offset,FFS_SIZEOF_BLOCKALLOC) != 0)	 return -1;      // Make sure it is allocated      if (isflagset(alloc->Status,FFS_ALLOC_SMASK,FFS_ALLOC_ALLOCATED) == 0 &&	  isflagset(alloc->Status,FFS_ALLOC_SMASK,FFS_ALLOC_DEALLOCATED) == 0)      {	 // End of the list	 if (isflagset(alloc->Status,FFS_ALLOC_EMASK,FFS_ALLOC_END) != 0)	    break;	 continue;      }            if (isflagset(alloc->Status,FFS_ALLOC_SMASK,FFS_ALLOC_DEALLOCATED) != 0)	 info->ReclaimableSpace += alloc->Len;      // Record the block data      offset = (alloc->Offset[2] << 16) + (alloc->Offset[1] << 8) + alloc->Offset[0];      if (insert_region(spaces,max,offset,alloc->Len) != 0)	 return -1;      // End of the list      if (isflagset(alloc->Status,FFS_ALLOC_EMASK,FFS_ALLOC_END) != 0)	 break;   }/*   printk("free list for %lu - %lu %lu\n",block,cur,r->location);   for (cur = 0; spaces[cur].Stop != 0 || spaces[cur].Start != 0; cur++)      printk("  at %lu %lu\n",spaces[cur].Start,spaces[cur].Stop);*/      // Invert the list to get a list of free spaces   cur = 0;   if (spaces[0].Start != 0)   {      memmove(spaces+1,spaces,(max - 1)*sizeof(*spaces));      spaces[0].Start = 1;      spaces[0].Stop = 0;   }   info->FreeSpace = 0;   info->LargestSpace = 0;   for (; spaces[cur].Stop != 0 || spaces[cur].Start != 0; cur++)   {      spaces[cur].Start = spaces[cur].Stop;      spaces[cur].Stop = spaces[cur+1].Start;      if (spaces[cur].Stop == 0)      {	 spaces[cur].Start = 0;	 continue;      }            info->FreeSpace += spaces[cur].Stop - spaces[cur].Start;      if (info->LargestSpace < spaces[cur].Stop - spaces[cur].Start)	 info->LargestSpace = spaces[cur].Stop - spaces[cur].Start;   }   // Store the allocation list   info->FreeList = kmalloc(sizeof(*info->FreeList)*cur,GFP_KERNEL);   memmove(info->FreeList,spaces,sizeof(*info->FreeList)*cur);      return 0;}									/*}}}*/// ffs2_prepare_info - Prepares the block info structures		/*{{{*/// ---------------------------------------------------------------------/* Generate a mapping of block sequence numbers to real block numbers and   make sure that we have no holes. This also should repair any damage   from an abortive reclimation process */static int ffs2_prepare_info(struct ffs_read *r){   unsigned I;   struct ffs2_sb_info *sb = &getFFS2_sb(r->super);   unsigned Blocks = sb->Boot.TotalBlockCount - sb->Boot.SpareBlockCount;   sb->Blocks = kmalloc(sizeof(*sb->Blocks)*sb->Boot.TotalBlockCount,			GFP_KERNEL);   if (sb->Blocks == 0)      return -1;   memset(sb->Blocks,0,sizeof(*sb->Blocks)*sb->Boot.TotalBlockCount);         // Generate the reverse mapping   for (I = 0; I != Blocks; I++)   {      if (ffs2_make_free_list(r,sb->BlockMap[I]) != 0)      {	 kfree(sb->Blocks);	 sb->Blocks = 0;	 return -1;      }                  sb->Blocks[sb->BlockMap[I]].VirtualBlock = I;   }      return 0;}									/*}}}*/// find_free_alloc - Find and allocate some space			/*{{{*/// ---------------------------------------------------------------------/* This tries to allocate some space for writing new data too. Block    acts as a hint of where to place the allocation or -1 if it does not   matter. Writing consists of      1 Locate a free allocation block     2 Extend the list     3 Write the offset and length     4 Indicate the block is allocated   Failures can occure at any point. The only tricky failure is betten 3   and 4, this is detected by ensuring the fields of an unused entry are   actually FF. Once point 4 is passed then the block is permanently    allocated and a failure before it is linked into any lists will leave   it hanging around forever. */static unsigned long find_free_alloc(struct ffs_read *r,				     struct ffs2_blockalloc *outalloc,				     unsigned long len,long block){   struct ffs2_sb_info *sb = &getFFS2_sb(r->super);   struct ffs2_sb_block *info;   unsigned int I;   unsigned int writeblock;   unsigned long cur;   unsigned long offset;   long best = -1;   struct ffs2_blockalloc *alloc;

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
精品国产一区二区三区久久久蜜月 | 盗摄精品av一区二区三区| 欧美一级二级三级乱码| 精品一区二区三区不卡| 国产精品传媒视频| 日韩三级免费观看| 欧美一级二级在线观看| 欧美成人福利视频| 欧美色欧美亚洲另类二区| 国产美女精品人人做人人爽| 亚洲一区二区三区视频在线播放| 久久综合国产精品| 欧美精品自拍偷拍| av电影一区二区| 韩国三级在线一区| 日本不卡一二三| 亚洲你懂的在线视频| 久久久欧美精品sm网站| 4438x亚洲最大成人网| 日本久久电影网| 成人av在线网站| 国产精品123区| 激情欧美日韩一区二区| 国产麻豆一精品一av一免费| 成人免费视频网站在线观看| 在线观看av一区| 色综合久久88色综合天天| 国产成人av电影在线播放| 久久99国产精品久久99| 成av人片一区二区| 欧美老年两性高潮| 国产日韩欧美不卡| 久久久久国产精品麻豆ai换脸 | 日韩电影在线看| 亚洲一区二区在线观看视频| 美腿丝袜在线亚洲一区| 日日夜夜精品视频免费| 日本视频一区二区三区| 高清av一区二区| 欧美电影一区二区三区| 中文字幕一区二区在线播放| 亚洲欧美偷拍三级| 国产自产v一区二区三区c| 色偷偷88欧美精品久久久| 欧美国产日产图区| 久久精品一区二区三区不卡 | 国产情人综合久久777777| 亚洲综合色区另类av| 国产精品1024久久| 日韩欧美黄色影院| 91精品国产91久久久久久一区二区| 3atv一区二区三区| 亚洲欧美韩国综合色| 久久精品国产精品亚洲精品| 国产美女精品人人做人人爽| 777色狠狠一区二区三区| 亚洲品质自拍视频网站| 国产成人一区在线| 欧美大黄免费观看| 丝袜亚洲精品中文字幕一区| 99精品国产91久久久久久| 色哟哟一区二区三区| 国产欧美一区二区三区网站 | 国产剧情一区二区三区| 成人av高清在线| 久久久久久久综合| 韩国精品一区二区| 日韩欧美国产午夜精品| 天堂成人国产精品一区| 在线成人免费观看| 丝袜美腿亚洲色图| 9191国产精品| 蜜桃免费网站一区二区三区| 3751色影院一区二区三区| 日本aⅴ精品一区二区三区| 制服视频三区第一页精品| 亚洲福利视频一区| 国产盗摄一区二区三区| 久久亚洲精精品中文字幕早川悠里| 日本不卡视频一二三区| 日韩精品中文字幕在线一区| 九一九一国产精品| 久久久国产精华| 不卡一区中文字幕| 一区二区三区.www| 成人黄色av网站在线| 国产精品毛片大码女人| 韩国精品主播一区二区在线观看 | 精品裸体舞一区二区三区| 国产中文字幕一区| 国产精品网曝门| 色菇凉天天综合网| 丝袜亚洲另类欧美综合| 久久伊人中文字幕| jizz一区二区| 午夜欧美2019年伦理| 99麻豆久久久国产精品免费优播| 国产精品毛片大码女人 | 亚洲国产精品久久人人爱蜜臀 | 国产欧美一区二区精品秋霞影院| 国产成人超碰人人澡人人澡| 亚洲图片你懂的| 高清不卡在线观看| 亚洲一区二区成人在线观看| 制服丝袜亚洲播放| 成人午夜看片网址| 石原莉奈在线亚洲二区| 欧美激情中文字幕一区二区| 欧美亚洲国产怡红院影院| 亚洲精品一卡二卡| 91小视频免费看| 中文字幕中文字幕在线一区 | 日韩一区和二区| 成人av网站在线| 奇米亚洲午夜久久精品| 一区二区成人在线视频| 久久蜜桃香蕉精品一区二区三区| av综合在线播放| 蜜桃传媒麻豆第一区在线观看| 国产精品久99| 精品国产91久久久久久久妲己 | 精品国产乱码久久久久久免费| 99麻豆久久久国产精品免费| 久久精品国产亚洲5555| 亚洲一区二区三区视频在线播放| 久久综合久久综合久久| 欧美浪妇xxxx高跟鞋交| 成人激情电影免费在线观看| 蜜臀av国产精品久久久久| 亚洲一区免费观看| 国产精品成人在线观看| 国产日韩欧美电影| 欧美成人精精品一区二区频| 欧美日韩国产成人在线91| 日韩精品三区四区| 亚洲猫色日本管| 国产精品毛片高清在线完整版| 欧美成人高清电影在线| 欧美一区中文字幕| 欧美日韩国产美| 欧美亚洲另类激情小说| 91免费看视频| 成人动漫av在线| 国产99久久久久久免费看农村| 精品亚洲成av人在线观看| 奇米精品一区二区三区在线观看 | 国产精品自拍一区| 久久99久久久欧美国产| 日韩va欧美va亚洲va久久| 亚洲观看高清完整版在线观看 | 免费人成黄页网站在线一区二区| 一区二区在线观看免费| 国产精品国产三级国产专播品爱网 | 亚洲人成小说网站色在线| 亚洲国产精品v| 国产欧美日本一区视频| 欧美国产精品劲爆| 国产精品私人影院| 中文字幕日韩精品一区| 亚洲另类在线视频| 亚洲国产日产av| 日韩av高清在线观看| 美女视频黄久久| 国产成人在线免费| 91亚洲精华国产精华精华液| 91免费观看视频在线| 欧美私人免费视频| 日韩三级视频在线看| 久久久国产精品麻豆| 18涩涩午夜精品.www| 亚洲一区二区三区四区在线免费观看 | 国产欧美日韩激情| 亚洲天堂a在线| 午夜精品福利视频网站| 久久av资源网| 99精品久久99久久久久| 欧美精品久久久久久久多人混战| 日韩欧美资源站| 欧美激情一区二区在线| 一区二区三区在线观看视频| 热久久国产精品| 成人免费va视频| 欧美色图片你懂的| 久久美女艺术照精彩视频福利播放| 国产精品午夜免费| 手机精品视频在线观看| 国产经典欧美精品| 欧美日韩在线一区二区| 欧美精品一区二区三区在线| 成人欧美一区二区三区黑人麻豆| 亚洲成人在线网站| 亚洲一区二区在线视频| 久草这里只有精品视频| 色久综合一二码| 精品国产一区二区三区忘忧草 | 欧美韩国一区二区| 自拍视频在线观看一区二区| 久色婷婷小香蕉久久| 在线免费观看一区| 日本一区二区免费在线|