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

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

?? dir.c

?? Sanos Operating System Kernel ----------------------------- Sanos is an OS kernel for use in PC base
?? C
字號:
//
// dir.c
//
// Disk filesystem directory 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>

#define NAME_ALIGN_LEN(l) (((l) + 3) & ~3)

ino_t find_dir_entry(struct inode *dir, char *name, int len)
{
  unsigned int block;
  blkno_t blk;
  struct buf *buf;
  char *p;
  struct dentry *de;
  ino_t ino;

  if (len <= 0 || len >= MAXPATH) return NOINODE;
  if (!(dir->desc->flags & DFS_INODE_FLAG_DIRECTORY)) return NOINODE;

  for (block = 0; block < dir->desc->blocks; block++)
  {
    blk = get_inode_block(dir, block);
    if (blk == NOBLOCK) return -EIO;

    buf = get_buffer(dir->fs->cache, blk);
    if (!buf) return -EIO;

    p = buf->data;
    while (p < buf->data + dir->fs->blocksize)
    {
      de = (struct dentry *) p;

      if (fnmatch(name, len, de->name, de->namelen))
      {
	ino = de->ino;
        release_buffer(dir->fs->cache, buf);
	return ino;
      }

      p += de->reclen;
    }

    release_buffer(dir->fs->cache, buf);
  }

  return NOINODE;
}

ino_t lookup_name(struct filsys *fs, ino_t ino, char *name, int len)
{
  char *p;
  int l;
  struct inode *inode;

  while (1)
  {
    // Skip path separator
    if (*name == PS1 || *name == PS2)
    {
      name++;
      len--;
    }
    if (len == 0) return ino;

    // Find next part of name
    p = name;
    l = 0;
    while (l < len && *p != PS1 && *p != PS2)
    {
      l++;
      p++;
    }

    // Find inode for next name part
    inode = get_inode(fs, ino);
    if (!inode) return NOINODE;
    ino = find_dir_entry(inode, name, l);
    release_inode(inode);
    if (ino == -1) return NOINODE;

    // If we have parsed the whole name return the inode number
    if (l == len) return ino;

    // Prepare for next name part
    name = p;
    len -= l;
  }
}

struct inode *parse_name(struct filsys *fs, char **name, int *len)
{
  char *start;
  char *p;
  ino_t ino;
  struct inode *dir;

  if (*len == 0) return get_inode(fs, DFS_INODE_ROOT);

  start = *name;
  p = start + *len - 1;
  while (p > start && *p != PS1 && *p != PS2) p--;

  if (p == start)
  {
    if (*p == PS1 || *p == PS2)
    {
      (*name)++;
      (*len)--;
    }

    return get_inode(fs, DFS_INODE_ROOT);
  }

  ino = lookup_name(fs, DFS_INODE_ROOT, start, p - start);
  if (ino == NOINODE) return NULL;

  dir = get_inode(fs, ino);
  if (!dir) return NULL;

  if (!(dir->desc->flags & DFS_INODE_FLAG_DIRECTORY))
  {
    release_inode(dir);
    return NULL;
  }

  *name = p + 1;
  *len -= p - start + 1;
  return dir;
}

int add_dir_entry(struct inode *dir, char *name, int len, ino_t ino)
{
  unsigned int block;
  blkno_t blk;
  struct buf *buf;
  char *p;
  struct dentry *de;
  struct dentry *newde;
  int minlen;

  if (len <= 0 || len >= MAXPATH) return -ENAMETOOLONG;
  if (!(dir->desc->flags & DFS_INODE_FLAG_DIRECTORY)) return -ENOTDIR;

  for (block = 0; block < dir->desc->blocks; block++)
  {
    blk = get_inode_block(dir, block);
    if (blk == NOBLOCK) return -EIO;

    buf = get_buffer(dir->fs->cache, blk);
    if (!buf) return -EIO;

    p = buf->data;
    while (p < buf->data + dir->fs->blocksize)
    {
      de = (struct dentry *) p;
      minlen = sizeof(struct dentry) + NAME_ALIGN_LEN(de->namelen);

      if (de->reclen >= minlen + sizeof(struct dentry) + NAME_ALIGN_LEN(de->namelen))
      {
	newde = (struct dentry *) (p + minlen);

	newde->ino = ino;
	newde->reclen = de->reclen - minlen;
	newde->namelen = len;
	memcpy(newde->name, name, len);

	de->reclen = minlen;

	mark_buffer_updated(dir->fs->cache, buf);
        release_buffer(dir->fs->cache, buf);

	dir->desc->mtime = time(NULL);
	mark_inode_dirty(dir);

	return 0;
      }

      p += de->reclen;
    }

    release_buffer(dir->fs->cache, buf);
  }

  blk = expand_inode(dir);
  if (blk == NOBLOCK) return -ENOSPC;

  buf = alloc_buffer(dir->fs->cache, blk);
  if (!buf) return -ENOMEM;

  dir->desc->size += dir->fs->blocksize;
  dir->desc->mtime = time(NULL);
  mark_inode_dirty(dir);

  newde = (struct dentry *) (buf->data);
  newde->ino = ino;
  newde->reclen = dir->fs->blocksize;
  newde->namelen = len;
  memcpy(newde->name, name, len);

  mark_buffer_updated(dir->fs->cache, buf);
  release_buffer(dir->fs->cache, buf);

  return 0;
}

ino_t modify_dir_entry(struct inode *dir, char *name, int len, ino_t ino)
{
  unsigned int block;
  blkno_t blk;
  struct buf *buf;
  char *p;
  struct dentry *de;
  ino_t oldino;

  if (len <= 0 || len >= MAXPATH) return NOINODE;
  if (!(dir->desc->flags & DFS_INODE_FLAG_DIRECTORY)) return NOINODE;

  for (block = 0; block < dir->desc->blocks; block++)
  {
    blk = get_inode_block(dir, block);
    if (blk == NOBLOCK) return NOINODE;

    buf = get_buffer(dir->fs->cache, blk);
    if (!buf) return NOINODE;

    p = buf->data;
    while (p < buf->data + dir->fs->blocksize)
    {
      de = (struct dentry *) p;

      if (fnmatch(name, len, de->name, de->namelen))
      {
	oldino = de->ino;
	de->ino = ino;
	mark_buffer_updated(dir->fs->cache, buf);
        release_buffer(dir->fs->cache, buf);
	return oldino;
      }

      p += de->reclen;
    }

    release_buffer(dir->fs->cache, buf);
  }

  return NOINODE;
}

int delete_dir_entry(struct inode *dir, char *name, int len)
{
  unsigned int block;
  blkno_t blk;
  blkno_t lastblk;
  struct buf *buf;
  char *p;
  struct dentry *de;
  struct dentry *prevde;
  struct dentry *nextde;

  if (len <= 0 || len >= MAXPATH) return -ENAMETOOLONG;
  if (!(dir->desc->flags & DFS_INODE_FLAG_DIRECTORY)) return -ENOTDIR;

  for (block = 0; block < dir->desc->blocks; block++)
  {
    blk = get_inode_block(dir, block);
    if (blk == NOBLOCK) return -EIO;

    buf = get_buffer(dir->fs->cache, blk);
    if (!buf) return -EIO;

    p = buf->data;
    prevde = NULL;
    while (p < buf->data + dir->fs->blocksize)
    {
      de = (struct dentry *) p;

      if (fnmatch(name, len, de->name, de->namelen))
      {
	if (prevde)
	{
	  // Merge entry with previous entry
	  prevde->reclen += de->reclen;
	  memset(de, 0, sizeof(struct dentry) + NAME_ALIGN_LEN(de->namelen));
          mark_buffer_updated(dir->fs->cache, buf);
	}
	else if (de->reclen == dir->fs->blocksize)
	{
	  // Block is empty, swap this block with last block and truncate
	  if (block != dir->desc->blocks - 1)
	  {
	    lastblk = get_inode_block(dir, dir->desc->blocks - 1);
	    if (lastblk == NOBLOCK) return -EIO;
  	    set_inode_block(dir, block, lastblk);
  	    set_inode_block(dir, dir->desc->blocks - 1, buf->blkno);
	  }

          truncate_inode(dir, dir->desc->blocks - 1);
	  dir->desc->size -= dir->fs->blocksize;
	  mark_buffer_invalid(dir->fs->cache, buf);
	}
	else
	{
	  // Merge with next entry
	  nextde = (struct dentry *) (p + de->reclen);
	  de->ino = nextde->ino;
	  de->reclen += nextde->reclen;
	  de->namelen = nextde->namelen;
	  memcpy(de->name, nextde->name, nextde->namelen); // TODO: should be memmove?
  	  mark_buffer_updated(dir->fs->cache, buf);
	}

        release_buffer(dir->fs->cache, buf);

	dir->desc->mtime = time(NULL);
	mark_inode_dirty(dir);

	return 0;
      }

      prevde = de;
      p += de->reclen;
    }

    release_buffer(dir->fs->cache, buf);
  }

  return -ENOENT;
}

int iterate_dir(struct inode *dir, filldir_t filldir, void *data)
{
  unsigned int block;
  blkno_t blk;
  struct buf *buf;
  char *p;
  struct dentry *de;
  int rc;

  if (!(dir->desc->flags & DFS_INODE_FLAG_DIRECTORY)) return -ENOTDIR;

  for (block = 0; block < dir->desc->blocks; block++)
  {
    blk = get_inode_block(dir, block);
    if (blk == NOBLOCK) return -EIO;

    buf = get_buffer(dir->fs->cache, blk);
    if (!buf) return -EIO;

    p = buf->data;
    while (p < buf->data + dir->fs->blocksize)
    {
      de = (struct dentry *) p;

      rc = filldir(de->name, de->namelen, de->ino, data);
      if (rc != 0)
      {
        release_buffer(dir->fs->cache, buf);
	return rc;
      }

      p += de->reclen;
    }

    release_buffer(dir->fs->cache, buf);
  }

  return 0;
}

int dfs_opendir(struct file *filp, char *name)
{
  struct filsys *fs;
  int len;
  ino_t ino;
  struct inode *inode;

  fs = (struct filsys *) filp->fs->data;
  len = strlen(name);

  ino = lookup_name(fs, DFS_INODE_ROOT, name, len);
  if (ino == NOINODE) return -ENOENT;
  
  inode = get_inode(fs, ino);
  if (!inode) return -EIO;

  if (!(inode->desc->flags & DFS_INODE_FLAG_DIRECTORY))
  {
    release_inode(inode);
    return -ENOTDIR;
  }

  filp->data = inode;
  return 0;
}

int dfs_readdir(struct file *filp, struct dirent *dirp, int count)
{
  unsigned int iblock;
  unsigned int start;
  struct inode *inode;
  blkno_t blk;
  struct buf *buf;
  struct dentry *de;

  inode = (struct inode *) filp->data;
  if (count != 1) return -EINVAL;
  if (filp->pos == inode->desc->size) return 0;
  if (filp->pos > inode->desc->size) return 0;

  iblock = filp->pos / inode->fs->blocksize;
  start = filp->pos % inode->fs->blocksize;

  blk = get_inode_block(inode, iblock);
  if (blk == NOBLOCK) return -EIO;

  buf = get_buffer(inode->fs->cache, blk);
  if (!buf) return -EIO;

  de = (struct dentry *) (buf->data + start);
  if (de->reclen + start > inode->fs->blocksize || de->namelen <= 0 || de->namelen >= MAXPATH)
  {
    release_buffer(inode->fs->cache, buf);
    return 0;
  }

  dirp->ino = de->ino;
  dirp->reclen = de->reclen;
  dirp->namelen = de->namelen;
  memcpy(dirp->name, de->name, de->namelen);
  dirp->name[de->namelen] = 0;
  
  filp->pos += de->reclen;

  release_buffer(inode->fs->cache, buf);
  return 1;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
丁香激情综合国产| 日韩欧美三级在线| 欧美一区二区高清| 欧美国产精品劲爆| 日韩av高清在线观看| 国产.欧美.日韩| 欧美日韩在线精品一区二区三区激情 | 日韩高清在线一区| 99久久免费视频.com| 日韩一卡二卡三卡国产欧美| 亚洲人吸女人奶水| 黄色资源网久久资源365| 91成人在线观看喷潮| 国产欧美va欧美不卡在线| 首页亚洲欧美制服丝腿| 99re亚洲国产精品| 国产视频一区在线观看| 欧美a级一区二区| 在线91免费看| 日韩在线a电影| 欧美理论在线播放| 亚洲sss视频在线视频| 成人黄色国产精品网站大全在线免费观看 | 中文字幕av一区二区三区免费看 | 日日夜夜免费精品视频| 亚洲精品在线电影| 亚洲成人精品一区二区| jiyouzz国产精品久久| 久久久高清一区二区三区| 男女男精品视频网| 91麻豆精品国产自产在线 | 日韩免费观看高清完整版在线观看| 亚洲欧美另类久久久精品2019 | 亚洲r级在线视频| 欧美日韩在线观看一区二区 | 成人手机电影网| 国产色综合久久| 国产风韵犹存在线视精品| 久久亚洲私人国产精品va媚药| 老色鬼精品视频在线观看播放| 7777精品伊人久久久大香线蕉完整版 | 成年人国产精品| 国产精品乱人伦中文| 成人高清免费在线播放| 中文字幕一区三区| 色av成人天堂桃色av| 亚洲图片有声小说| 91精品在线麻豆| 精品一二三四区| 国产丝袜美腿一区二区三区| 成人夜色视频网站在线观看| 亚洲欧洲日产国码二区| 色婷婷激情综合| 午夜久久久久久久久| 日韩视频一区二区三区在线播放| 国产在线一区二区| 亚洲国产精品精华液网站| 欧美日韩精品一区二区三区蜜桃| 日韩国产精品久久久| 国产日韩综合av| 一本色道亚洲精品aⅴ| 亚洲成av人片在线| 精品国产乱码久久久久久免费| 成人网男人的天堂| 亚洲高清免费观看| 久久久精品日韩欧美| 91免费观看视频| 日韩高清不卡一区二区三区| 久久久www成人免费毛片麻豆 | 久久久久久久久久久久久久久99 | 久久av资源网| 亚洲私人影院在线观看| 日韩一二三区视频| 99久久精品免费看| 久久精品国产精品亚洲红杏 | 玉米视频成人免费看| 日韩欧美国产一区在线观看| 国产成人一区在线| 日韩精品1区2区3区| 久久久久九九视频| 这里只有精品免费| 97精品超碰一区二区三区| 午夜国产不卡在线观看视频| 国产精品网站一区| 日韩精品影音先锋| 色吧成人激情小说| 成人在线视频首页| 久草中文综合在线| 亚洲高清免费观看| 成人免费在线播放视频| 亚洲另类春色校园小说| 久久久久久久久一| 91精品中文字幕一区二区三区| 99国产精品99久久久久久| 国产麻豆9l精品三级站| 首页国产丝袜综合| 亚洲综合视频在线| 中文字幕人成不卡一区| 久久午夜色播影院免费高清 | 亚洲一区二区三区精品在线| 欧美高清一级片在线观看| 精品久久久久久久久久久院品网| 欧美自拍偷拍午夜视频| 91在线国产观看| 成人免费毛片aaaaa**| 国产在线播放一区二区三区| 青青草国产精品97视觉盛宴| 亚洲电影一区二区三区| 中文字幕国产一区| 国产欧美日韩精品a在线观看| 精品国产免费人成在线观看| 欧美一区二区三区免费观看视频| 欧美日韩一区 二区 三区 久久精品| av中文字幕亚洲| 粉嫩绯色av一区二区在线观看| 国产在线视频精品一区| 国产在线精品不卡| 国产成人在线看| 成人av片在线观看| 99精品黄色片免费大全| 97se狠狠狠综合亚洲狠狠| 成人av一区二区三区| 99久久国产综合精品麻豆| 99在线视频精品| 色婷婷av一区二区三区大白胸| 色综合久久久久网| 欧美在线看片a免费观看| 欧美日韩视频在线第一区| 欧美精品色综合| 日韩三级视频中文字幕| 26uuu亚洲综合色| 国产三级欧美三级日产三级99| 日本一区二区三区国色天香| 国产精品毛片无遮挡高清| 亚洲人成伊人成综合网小说| 亚洲国产日韩精品| 免费人成精品欧美精品| 国产麻豆视频精品| 成人av网址在线| 欧美日韩精品福利| 日韩欧美的一区| 国产日韩在线不卡| 一区二区三区四区不卡在线 | 国产欧美一区二区三区在线看蜜臀| 久久精品一区蜜桃臀影院| 中文字幕一区二区不卡| 五月婷婷久久综合| 国精品**一区二区三区在线蜜桃| 国产成人av一区二区三区在线观看| 99久久伊人网影院| 欧美高清激情brazzers| 国产午夜精品一区二区三区四区| 亚洲视频综合在线| 麻豆久久久久久久| 一本到不卡精品视频在线观看| 91精品一区二区三区在线观看| 久久久久久久精| 国产99精品国产| 在线视频亚洲一区| 26uuu国产日韩综合| 亚洲摸摸操操av| 精品无码三级在线观看视频| 91在线观看成人| 精品久久久久久亚洲综合网| 一区二区在线电影| 国产一区二区不卡老阿姨| 欧美亚洲一区二区三区四区| 国产日韩欧美精品电影三级在线| 亚洲成av人片www| 成人av手机在线观看| 精品区一区二区| 亚洲一区二区三区爽爽爽爽爽| 国产成人av电影免费在线观看| 欧美日韩一区二区三区四区五区| 国产三级精品三级在线专区| 美女精品一区二区| 欧美日韩中文一区| 亚洲女与黑人做爰| 成人黄色在线视频| 国产无一区二区| 毛片av一区二区| 在线综合亚洲欧美在线视频| 亚洲影视资源网| 99免费精品在线观看| 国产欧美一区二区三区沐欲| 看片的网站亚洲| 51精品国自产在线| 亚洲成av人影院| 欧美影院一区二区三区| 中文字幕中文字幕一区二区 | 日本午夜一区二区| 欧美三级视频在线观看| 亚洲精品日日夜夜| 95精品视频在线| 亚洲丝袜另类动漫二区| 成人黄色大片在线观看| 国产精品国产精品国产专区不片| 国产精品综合av一区二区国产馆| 日韩精品一区二区三区视频在线观看 | 国产亚洲福利社区一区|