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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? inode.c

?? Sanos Operating System Kernel ----------------------------- Sanos is an OS kernel for use in PC base
?? C
字號:
//
// inode.c
//
// Disk filesystem inode routines
//
// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 
// 1. Redistributions of source code must retain the above copyright 
//    notice, this list of conditions and the following disclaimer.  
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.  
// 3. Neither the name of the project nor the names of its contributors
//    may be used to endorse or promote products derived from this software
//    without specific prior written permission. 
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
// SUCH DAMAGE.
// 

#include <os/krnl.h>

static void split_levels(struct inode *inode, unsigned int iblock, unsigned int offsets[DFS_MAX_DEPTH])
{
  unsigned int shift;
  int d;

  shift = inode->desc->depth * inode->fs->log_blkptrs_per_block;
  offsets[0] = iblock >> shift;

  for (d = 1; d <= inode->desc->depth; d++)
  {
    iblock &= ((1 << shift) - 1);
    shift -= inode->fs->log_blkptrs_per_block;
    offsets[d] = iblock >> shift;
  }
}

void mark_inode_dirty(struct inode *inode)
{
  mark_buffer_updated(inode->fs->cache, inode->buf);
}

blkno_t get_inode_block(struct inode *inode, unsigned int iblock)
{
  int d;
  blkno_t block;
  struct buf *buf;
  unsigned int offsets[DFS_MAX_DEPTH];

  split_levels(inode, iblock, offsets);
  block = inode->desc->blockdir[offsets[0]];

  for (d = 1; d <= inode->desc->depth; d++)
  {
    buf = get_buffer(inode->fs->cache, block);
    if (!buf) return NOBLOCK;

    block = ((blkno_t *) buf->data)[offsets[d]];
    release_buffer(inode->fs->cache, buf);

    if (!block) return NOBLOCK;
  }

  return block;
}

blkno_t set_inode_block(struct inode *inode, unsigned int iblock, blkno_t block)
{
  int d;
  struct buf *buf;
  blkno_t dirblock;
  blkno_t goal;
  unsigned int offsets[DFS_MAX_DEPTH];

  goal = inode->ino / inode->fs->super->inodes_per_group * inode->fs->super->blocks_per_group;

  if (inode->desc->depth == 0)
  {
    // Allocate new block in same group as inode if requested
    if (block == NOBLOCK) 
    {
      block = new_block(inode->fs, goal);
      if (block == NOBLOCK) return NOBLOCK;
      inode->desc->blocks++;
    }

    // Update top block directory in inode descriptor
    inode->desc->blockdir[iblock] = block;
    mark_inode_dirty(inode);
  }
  else
  {
    buf = NULL;

    // Get block directory block for first level
    split_levels(inode, iblock, offsets);
    dirblock = inode->desc->blockdir[offsets[0]];

    // Allocate block and update inode
    if (dirblock == 0)
    {
      dirblock = new_block(inode->fs, goal);
      if (dirblock == NOBLOCK) return NOBLOCK;

      inode->desc->blockdir[offsets[0]] = dirblock;
      mark_inode_dirty(inode);

      buf = alloc_buffer(inode->fs->cache, dirblock);
      if (!buf) return NOBLOCK;
      memset(buf->data, 0, inode->fs->blocksize);
    }

    // Traverse and allocate internal pages in block directory
    for (d = 1; d < inode->desc->depth; d++)
    {
      // Get directory page for next level
      if (!buf) buf = get_buffer(inode->fs->cache, dirblock);
      if (!buf) return NOBLOCK;
      goal = dirblock + 1;
      dirblock = ((blkno_t *) buf->data)[offsets[d]];

      // Allocate directory page block if missing        
      if (dirblock == 0)
      {
        dirblock = new_block(inode->fs, goal);
	if (dirblock == NOBLOCK) return NOBLOCK;
        ((blkno_t *) buf->data)[offsets[d]] = dirblock;
        mark_buffer_updated(inode->fs->cache, buf);
        release_buffer(inode->fs->cache, buf);

	buf = alloc_buffer(inode->fs->cache, dirblock);
	if (!buf) return NOBLOCK;
	memset(buf->data, 0, inode->fs->blocksize);
      }
      else
      {
        release_buffer(inode->fs->cache, buf);
        buf = NULL;
      }
    }
    
    // Get leaf block directory page
    if (!buf) buf = get_buffer(inode->fs->cache, dirblock);
    if (!buf) return NOBLOCK;

    // Allocate new block near previous block or leaf directory page if requested
    if (block == -1) 
    {
      block = new_block(inode->fs, offsets[d] == 0 ? dirblock + 1 : ((blkno_t *) buf->data)[offsets[d] - 1] + 1);
      if (block == NOBLOCK) return NOBLOCK;
      inode->desc->blocks++;
      mark_inode_dirty(inode);
    }

    // Update leaf with new block
    ((blkno_t *) buf->data)[offsets[d]] = block;
    mark_buffer_updated(inode->fs->cache, buf);
    release_buffer(inode->fs->cache, buf);
  }

  return block;
}

struct inode *alloc_inode(struct inode *parent, int flags)
{
  ino_t ino;
  struct inode *inode;
  unsigned int group;
  unsigned int block;

  ino = new_inode(parent->fs, parent->ino, flags);
  if (ino == -1) return NULL; 

  inode = (struct inode *) kmalloc(sizeof(struct inode));
  if (!inode) return NULL;

  inode->fs = parent->fs;
  inode->ino = ino;

  group = ino / inode->fs->super->inodes_per_group;
  block = inode->fs->groups[group].desc->inode_table_block + (ino % inode->fs->super->inodes_per_group) / inode->fs->inodes_per_block;

  inode->buf = get_buffer(inode->fs->cache, block);
  if (!inode->buf)
  {
    kfree(inode);
    return NULL;
  }
  inode->desc = (struct inodedesc *) (inode->buf->data) + (ino % inode->fs->inodes_per_block);

  memset(inode->desc, 0, sizeof(struct inodedesc));
  inode->desc->flags = flags;
  inode->desc->ctime = inode->desc->mtime = time(NULL);

  mark_inode_dirty(inode);

  return inode;  
}

int unlink_inode(struct inode *inode)
{
  int rc;

  inode->desc->linkcount--;
  mark_inode_dirty(inode);
  if (inode->desc->linkcount > 0) return 0;

  rc = truncate_inode(inode, 0);
  if (rc < 0) return rc;

  memset(inode->desc, 0, sizeof(struct inodedesc));

  free_inode(inode->fs, inode->ino);

  return 0;
}

struct inode *get_inode(struct filsys *fs, ino_t ino)
{
  struct inode *inode;
  unsigned int group;
  unsigned int block;

  inode = (struct inode *) kmalloc(sizeof(struct inode));
  if (!inode) return NULL;

  inode->fs = fs;
  inode->ino = ino;

  group = ino / fs->super->inodes_per_group;
  block = fs->groups[group].desc->inode_table_block + (ino % fs->super->inodes_per_group) / fs->inodes_per_block;

  inode->buf = get_buffer(fs->cache, block);
  if (!inode->buf)
  {
    kfree(inode);
    return NULL;
  }
  inode->desc = (struct inodedesc *) (inode->buf->data) + (ino % fs->inodes_per_block);

  return inode;  
}

void release_inode(struct inode *inode)
{
  if (inode->buf) release_buffer(inode->fs->cache, inode->buf);
  kfree(inode);
}

blkno_t expand_inode(struct inode *inode)
{
  unsigned int maxblocks;
  unsigned int dirblock;
  unsigned int i;
  struct buf *buf;

  // Increase depth of block directory tree if tree is full
  maxblocks = DFS_TOPBLOCKDIR_SIZE * (1 << (inode->desc->depth * inode->fs->log_blkptrs_per_block));
  if (inode->desc->blocks == maxblocks)
  {
    // Allocate block for new directory page
    dirblock = new_block(inode->fs, inode->desc->blockdir[0] - 1);
    if (dirblock == NOBLOCK) return NOBLOCK;

    // Move top directory entries to new directory page
    buf = alloc_buffer(inode->fs->cache, dirblock);
    if (!buf) return NOBLOCK;
    memset(buf->data, 0, inode->fs->blocksize);
    for (i = 0; i < DFS_TOPBLOCKDIR_SIZE; i++)
    {
      ((blkno_t *) buf->data)[i] = inode->desc->blockdir[i];
      inode->desc->blockdir[i] = 0;
    }

    // Set top block dir to point to new directory page and increase depth
    inode->desc->blockdir[0] = dirblock;
    inode->desc->depth++;

    mark_buffer_updated(inode->fs->cache, buf);
    mark_inode_dirty(inode);
    release_buffer(inode->fs->cache, buf);
  }

  // Allocate new block and add to inode block directory
  return set_inode_block(inode, inode->desc->blocks, NOBLOCK);
}

static void remove_blocks(struct filsys *fs, blkno_t *blocks, int count)
{
  int i;

  if (count > 0)
  {
    for (i = 0; i < count; i++) invalidate_buffer(fs->cache, blocks[i]);
    free_blocks(fs, blocks, count);
    memset(blocks, 0, sizeof(blkno_t) * count);
  }
}

int truncate_inode(struct inode *inode, unsigned int blocks)
{
  int d;
  unsigned int iblock;
  unsigned int blocksleft;
  unsigned int count;
  blkno_t blk;
  unsigned int offsets[DFS_MAX_DEPTH];
  struct buf *buf[DFS_MAX_DEPTH];

  // Check arguments
  if (blocks > inode->desc->blocks) return -EINVAL;

  // Check for no-op case
  if (blocks == inode->desc->blocks) return 0;
  if (inode->desc->blocks == 0) return 0;

  // If depth 0 we just have to free blocks from top directory
  if (inode->desc->depth == 0)
  {
    remove_blocks(inode->fs, inode->desc->blockdir + blocks, inode->desc->blocks - blocks);
    inode->desc->blocks = blocks;
    mark_inode_dirty(inode);
    return 0;
  }

  // Clear buffers
  for (d = 0; d < DFS_MAX_DEPTH; d++) buf[d] = NULL;

  // Remove blocks from the end of the file until we reach the requested size
  iblock = inode->desc->blocks - 1;
  blocksleft = inode->desc->blocks - blocks;
  while (blocksleft > 0)
  {
    // Traverse block directory tree until we reach the last block
    split_levels(inode, iblock, offsets);
    blk = inode->desc->blockdir[offsets[0]];

    for (d = 1; d <= inode->desc->depth; d++)
    {
      if (!buf[d] || buf[d]->blkno != blk)
      {
	if (buf[d]) release_buffer(inode->fs->cache, buf[d]);
	buf[d] = get_buffer(inode->fs->cache, blk);
	if (!buf[d]) return -EIO;
      }
      blk = ((blkno_t *) buf[d]->data)[offsets[d]];
    }

    d = inode->desc->depth;
    if (blocksleft > offsets[d])
    {
      // Remove all blocks in leaf directory page and free it
      count = offsets[d] + 1;
      remove_blocks(inode->fs, (blkno_t *) buf[d]->data, count);
      free_blocks(inode->fs, &(buf[d]->blkno), 1);
      mark_buffer_invalid(inode->fs->cache, buf[d]);

      iblock -= count;
      blocksleft -= count;
      offsets[d] = 0;

      // Remove internal directory pages
      while (--d > 0)
      {
	((blkno_t *) buf[d]->data)[offsets[d]] = 0;
	if (offsets[d] == 0)
	{
          free_blocks(inode->fs, &(buf[d]->blkno), 1);
          mark_buffer_invalid(inode->fs->cache, buf[d]);
	}
	else
	{
  	  mark_buffer_updated(inode->fs->cache, buf[d]);
	  break;
	}
      }

      // Update top directory page in inode
      if (d == 0 && offsets[1] == 0)
      {
        inode->desc->blockdir[offsets[0]] = 0;
	mark_inode_dirty(inode);
      }
    }
    else
    {
      // Remove range of blocks in leaf directory page
      remove_blocks(inode->fs, (blkno_t *) buf[d]->data + offsets[d] + 1 - blocksleft, blocksleft);
      mark_buffer_updated(inode->fs->cache, buf[d]);

      iblock -= blocksleft;
      blocksleft = 0;
    }
  }

  // Release buffers
  for (d = 0; d < DFS_MAX_DEPTH; d++) 
  {
    if (buf[d]) release_buffer(inode->fs->cache, buf[d]);
  }

  // Update inode
  inode->desc->blocks = blocks;
  if (blocks == 0) inode->desc->depth = 0;
  mark_inode_dirty(inode);

  return 0;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
99精品国产热久久91蜜凸| 日韩黄色一级片| 欧美一级黄色片| 在线免费观看不卡av| 成人免费毛片a| 国产高清视频一区| 顶级嫩模精品视频在线看| 国产呦精品一区二区三区网站| 日本麻豆一区二区三区视频| 视频一区二区欧美| 日精品一区二区| 免费av成人在线| 看国产成人h片视频| 久久91精品久久久久久秒播| 免费在线观看视频一区| 91碰在线视频| 91在线一区二区三区| 色婷婷狠狠综合| 欧美日韩一级二级| 69久久夜色精品国产69蝌蚪网| 欧美蜜桃一区二区三区| 日韩一区二区三区观看| 久久无码av三级| 亚洲国产成人自拍| 亚洲精品免费电影| 偷拍一区二区三区| 韩国午夜理伦三级不卡影院| 成人国产免费视频| 91热门视频在线观看| 69堂精品视频| 久久久久久电影| 亚洲人精品午夜| 日本成人超碰在线观看| 国产精品亚洲专一区二区三区| av在线不卡电影| 欧美日本一区二区在线观看| 精品国产乱码久久久久久牛牛 | 国产日韩在线不卡| 亚洲色图欧美偷拍| 久久黄色级2电影| www.欧美色图| 91精品国产免费| 国产精品第13页| 日日摸夜夜添夜夜添国产精品 | xnxx国产精品| 亚洲精品美国一| 精品在线免费视频| 在线影院国内精品| 2021久久国产精品不只是精品| 六月丁香婷婷色狠狠久久| 国产精品一级片| 91麻豆精品国产91久久久使用方法 | 日韩欧美国产综合在线一区二区三区| 国产亚洲精品aa午夜观看| 夜夜爽夜夜爽精品视频| 国产精品影音先锋| 欧美一区二区免费| 亚洲综合视频在线观看| 懂色av一区二区夜夜嗨| 精品国产一区二区三区不卡| 一区二区三区国产精华| 成人白浆超碰人人人人| 日韩欧美国产成人一区二区| 亚洲欧美另类在线| 成人性生交大片免费看在线播放| 日韩欧美卡一卡二| 日韩制服丝袜先锋影音| 91久久人澡人人添人人爽欧美 | 久久精品国产99国产| 在线视频你懂得一区二区三区| 美女一区二区视频| 欧美午夜片在线观看| 亚洲人亚洲人成电影网站色| 国产suv精品一区二区6| 精品久久久久久综合日本欧美| 五月婷婷综合网| 欧美日韩在线播放三区四区| 一区二区三区自拍| 91麻豆国产香蕉久久精品| √…a在线天堂一区| 成年人午夜久久久| 日韩一区在线看| www.亚洲激情.com| 亚洲视频资源在线| 97久久超碰国产精品| 中文字幕色av一区二区三区| 成人精品国产免费网站| 中文字幕av一区 二区| www.成人在线| 日韩一区在线看| 色综合中文字幕国产 | 久久综合99re88久久爱| 麻豆一区二区三| 精品欧美乱码久久久久久1区2区| 久久97超碰国产精品超碰| 欧美精品一区二区久久久| 国产精品一区一区三区| 日本不卡一二三区黄网| 日韩三级在线免费观看| 国产一区二区三区蝌蚪| 亚洲国产经典视频| 欧美影院精品一区| 日本vs亚洲vs韩国一区三区二区 | 久久网站最新地址| 粉嫩13p一区二区三区| 亚洲日本中文字幕区| 欧美日韩国产综合久久| 日韩**一区毛片| 久久久精品天堂| 91在线观看成人| 日韩主播视频在线| 国产午夜亚洲精品午夜鲁丝片 | 一本到一区二区三区| 亚洲国产日韩在线一区模特| 亚洲欧美一区二区三区极速播放| 欧美在线视频全部完| 久久精品av麻豆的观看方式| 中文字幕 久热精品 视频在线| 在线免费观看一区| 国产一区三区三区| 亚洲一区在线观看免费观看电影高清| 日韩欧美国产一二三区| 99精品在线免费| 久久99精品国产.久久久久| 国产精品久久久久国产精品日日| 欧美久久久久免费| 本田岬高潮一区二区三区| 日韩av电影天堂| 亚洲人成7777| 国产亚洲综合性久久久影院| 欧美日韩一区二区欧美激情| 国产69精品久久久久777| 五月天视频一区| 亚洲丝袜自拍清纯另类| 精品成人一区二区三区四区| 欧美在线观看视频一区二区三区| 国产成人午夜99999| 另类综合日韩欧美亚洲| 亚洲一区二区综合| 国产精品国产三级国产有无不卡| 51精品视频一区二区三区| av中文字幕一区| 欧美精品一卡二卡| 91精品福利视频| www.亚洲色图.com| 国产·精品毛片| 国产精品亚洲一区二区三区妖精 | 精品无人码麻豆乱码1区2区 | 视频一区视频二区中文| 一区二区三区欧美视频| 综合久久国产九一剧情麻豆| 国产欧美精品区一区二区三区 | 中文字幕在线观看一区二区| 久久精品男人天堂av| 亚洲激情图片qvod| 最新国产精品久久精品| 国产精品美女久久福利网站| 久久久久久久精| 久久综合999| 欧美国产成人在线| 国产精品久久久久影视| 国产精品免费av| 国产精品国产三级国产专播品爱网 | 色悠悠亚洲一区二区| caoporn国产一区二区| 99热在这里有精品免费| 97久久精品人人澡人人爽| 91免费在线看| 欧美在线高清视频| 欧美一级精品在线| 欧美成人精品高清在线播放| 精品国产乱码久久久久久牛牛 | 成人免费观看视频| www.欧美精品一二区| 99久久伊人网影院| 欧日韩精品视频| 91精品麻豆日日躁夜夜躁| 欧美一区二区啪啪| 久久久不卡网国产精品二区| 中文字幕av在线一区二区三区| 最好看的中文字幕久久| 国产91在线|亚洲| 99久久婷婷国产综合精品电影| 在线一区二区三区做爰视频网站| 欧美日韩精品高清| 26uuu另类欧美| 综合网在线视频| 日本在线观看不卡视频| 国产精品18久久久久久vr| 97久久久精品综合88久久| 91麻豆精品国产91久久久久| 久久精品一区二区三区不卡| 亚洲精品国产无套在线观| 日韩黄色片在线观看| 成人性生交大片免费| 日韩视频免费直播| 国产精品日韩精品欧美在线 | 91精品国产色综合久久ai换脸 | 成人黄色综合网站| 欧美精品vⅰdeose4hd|