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

📄 mfs_filesys.c

📁 实用的程序代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////////////// Copyright (c) 2002 Xilinx, Inc.  All rights reserved.//// Xilinx, Inc.// // File   : mfs_filesys.c// Date   : 2002, March 20.// Company: Xilinx// Group  : Emerging Software Technologies//// Description : //// $Header: /devl/xcs/repo/env/Jobs/MDT/sw/os/xilmfs/src/mfs_filesys.c,v 1.1 2002/04/08 20:40:54 sid Exp $//////////////////////////////////////////////////////////////////////////////////#include <string.h>#include "xilmfs.h"struct mfs_file_block mfs_file_system[MFS_MAX_FILE_BLOCKS];int mfs_free_block_list;struct mfs_open_file_struct mfs_open_files[MFS_MAX_OPEN_FILES];int mfs_num_open_files; /* the number of mfs_open_files */int mfs_current_dir;/** * initialize the file system; * this function must be called before any file system operations */void mfs_init_fs() {  int i;  /* set the zeroth block to be a dir_block with itself as its parent */  /* initialize the free block list */  mfs_file_system[0].block_type = MFS_BLOCK_TYPE_DIR;  mfs_file_system[0].index = 0;  mfs_file_system[0].next_block = 0;  mfs_file_system[0].prev_block = 0;  mfs_file_system[0].u.dir_data.num_entries = 2; /* .. and . */  mfs_file_system[0].u.dir_data.num_deleted = 0;  strcpy(mfs_file_system[0].u.dir_data.dir_ent[0].name, "..");  mfs_file_system[0].u.dir_data.dir_ent[0].deleted = 'n';  mfs_file_system[0].u.dir_data.dir_ent[0].index = 0; /* .. = index of this block */  strcpy(mfs_file_system[0].u.dir_data.dir_ent[1].name, ".");  mfs_file_system[0].u.dir_data.dir_ent[1].deleted = 'n';  mfs_file_system[0].u.dir_data.dir_ent[1].index = 0; /* . = index of this block */  for (i = 1; i < MFS_MAX_FILE_BLOCKS; i++) {    mfs_file_system[i].block_type = MFS_BLOCK_TYPE_EMPTY;    mfs_file_system[i].next_block = i+1;    mfs_file_system[i].index = i;    mfs_file_system[i].prev_block = i-1;  }  mfs_file_system[MFS_MAX_FILE_BLOCKS-1].next_block = 0;  /* the last block points to 0 */  /* initialize free block list to the first free index = 1 */  mfs_free_block_list = 1;  /* initialize current dir to the top level */  mfs_current_dir = 0;  /* initialize mfs_open_files */  for (i = 0; i < MFS_MAX_OPEN_FILES; i++)    mfs_open_files[i].mode = MFS_MODE_FREE;  mfs_num_open_files = 0;}/** * return 0 for failure and 1 for success * on success: * return dir_block = index of dir block (may not always be mfs_current_dir) * return dir_index = index within dir_block or undefined on failure * on failure: * return dir_block = index of dir block that has the first "free entry" or  *                    index of last searched block which should have no free entries or *                    -1 to indicate error * return dir_index = index within dir_block of first free entry or  *                    MFS_MAX_LOCAL_ENT if last searched block has no free entry or *                    -1 to indicate error */static int get_dir_ent_base(const char *filename,  int *dir_block, int *dir_index) {  /* *dir_index = 0; *dir_block = valid dir corresponding to filename prefixes processed so far, on entry to this proc */  int numentriesleft = mfs_file_system[*dir_block].u.dir_data.num_entries;  char tmpfilename[MFS_MAX_FILENAME_LENGTH];  int index = 0;   while(*filename != '/' && *filename != '\0') {    tmpfilename[index] = *filename;     filename++;    index++;  }  tmpfilename[index] = '\0';  while (numentriesleft > 0) {    if (*dir_index == MFS_MAX_LOCAL_ENT) { /* move to the next dir block */      *dir_index = 0;      *dir_block = mfs_file_system[*dir_block].next_block;    }    if (mfs_file_system[*dir_block].u.dir_data.dir_ent[*dir_index].deleted != 'y' &&        !strcmp(mfs_file_system[*dir_block].u.dir_data.dir_ent[*dir_index].name,                 tmpfilename)) { /* found the entry */      /* *dir_index = index; */      /* *dir_block = dir; */      if (*filename == '\0'|| (*filename == '/' && *(filename+1)== '\0')) /* this is the base file name, ignore final '/' if present */        return 1;      else { /* tmpname is the current prefix, filename is the rest of the path */        *dir_block = mfs_file_system[*dir_block].u.dir_data.dir_ent[*dir_index].index;        *dir_index = 0;        filename++;        return(get_dir_ent_base(filename, dir_block, dir_index));      }            }    *dir_index += 1;    numentriesleft--;  }  if (*filename == '\0' || (*filename == '/' && *(filename+1)=='\0')) { /* could not find the base name but path prefix is correct */    return 0;  }  else { /* path prefix is wrong */    *dir_block = -1;    *dir_index = -1;    return 0;  }}/** * filename is an arbitrarily long  '/' separated path name  * each component of the path name is never longer than MFS_MAX_FILENAME_LENGTH * if the first character is '/', search starting at the root directory * else search starting at the current directory * return 0 for failure and 1 for success * on success: * return dir_block = index of dir block (may not always be mfs_current_dir) * return dir_index = index within dir_block or undefined on failure * on failure: * return dir_block = index of dir block that has the first "free entry" or  *                    index of last searched block which should have no free entries or *                    -1 to indicate error * return dir_index = index within dir_block of first free entry or  *                    MFS_MAX_LOCAL_ENT if last searched block has no free entry or *                    -1 to indicate error */static int get_dir_ent(const char *filename,  int *dir_block, int *dir_index) {  if (filename != NULL && *filename != '\0') {    if (*filename == '/') {      filename++;      *dir_block = 0;    }    else {      *dir_block = mfs_current_dir;    }    *dir_index = 0;    if (*filename == '\0') /* done - looking for the root directory */      return 1;    else      return(get_dir_ent_base(filename, dir_block, dir_index));  }  /* error condition */  *dir_block = -1;  *dir_index = -1;  return 0;}/** * return 0 for failure and 1 for success * on success: * return dir_block = index of dir block (may not always be mfs_current_dir) * return dir_index = index within dir_block or undefined on failure * on failure: * return dir_block = index of dir block that has the first "free entry" or  *                    index of last searched block which should have no free entries  * return dir_index = index within dir_block of first free entry or MFS_MAX_LOCAL_ENT if last searched block has no free entry*/// static int get_dir_ent_by_index(int file_index,  int *dir_block, int *dir_index) {//    int numentriesleft = mfs_file_system[mfs_current_dir].u.dir_data.num_entries;//   *dir_index = 0;//   *dir_block = mfs_current_dir;//   while (numentriesleft > 0) {//     if (*dir_index == MFS_MAX_LOCAL_ENT) { /* move to the next dir block *///       *dir_index = 0;//       *dir_block = mfs_file_system[*dir_block].next_block;//     }//     if (mfs_file_system[*dir_block].u.dir_data.dir_ent[*dir_index].deleted != 'y' &&// 	mfs_file_system[*dir_block].u.dir_data.dir_ent[*dir_index].index == file_index) { /* found the entry *///       /* *dir_index = index; *///       /* *dir_block = dir; *///       return 1;//     }//     *dir_index += 1;//     numentriesleft--;//   }//   return 0;// }static int get_dir_ent_by_index(int file_index,  int *dir_block, int *dir_index) {   int numentriesleft;      *dir_block = mfs_file_system[file_index].u.dir_data.dir_ent[0].index;   numentriesleft = mfs_file_system[*dir_block].u.dir_data.num_entries;   *dir_index = 0;      while (numentriesleft > 0) {      if (*dir_index == MFS_MAX_LOCAL_ENT) { /* move to the next dir block */         *dir_index = 0;         *dir_block = mfs_file_system[*dir_block].next_block;      }            if (mfs_file_system[*dir_block].u.dir_data.dir_ent[*dir_index].deleted != 'y' &&          mfs_file_system[*dir_block].u.dir_data.dir_ent[*dir_index].index == file_index) { /* found the entry */         /* *dir_index = index; */         /* *dir_block = dir; */         return 1;      }      *dir_index += 1;      numentriesleft--;   }   return 0;}/**  * modify mfs_current_dir to index of newdir if it exists * mfs_current_dir is not modified otherwise * return 1 for success and 0 for failure */int mfs_change_dir(const char *newdir) {  /* search current dir for newdir and change current dir if found */  /* return 1 for success, 0 for failure */  int new_dir_block;  int new_dir_index;  if (get_dir_ent(newdir, &new_dir_block, &new_dir_index)) {    mfs_current_dir = mfs_file_system[new_dir_block].u.dir_data.dir_ent[new_dir_index].index;    return 1;  }  return 0;}/** * allocate a new block from the free list * new_entry_index is modified to point to the newly allocated block * return 1 on success, 0 on failure */static int get_next_free_block(int *new_entry_index) {  if (mfs_free_block_list != 0) {    *new_entry_index = mfs_free_block_list;    /* update free_list */    mfs_free_block_list = mfs_file_system[*new_entry_index].next_block;    if (mfs_free_block_list != 0) {      mfs_file_system[mfs_free_block_list].prev_block = 0;    }    else {      /* free list is empty so do not update prev pointer of first element */    }    /* remove block from free list */    mfs_file_system[*new_entry_index].prev_block = 0;    mfs_file_system[*new_entry_index].next_block = 0;    return 1;  }  return 0; /* failed to get free block */}/** * create a new directory block, and initialize it with info about . and ..  * if this dir wants to know its name, it needs to ask its parent  */static int create_new_file(int file_type, int *new_entry_index, int parent_dir_block) {  if (get_next_free_block(new_entry_index)) {    if (file_type == MFS_BLOCK_TYPE_DIR) {      /* fill in the new dir block with .. and . */      mfs_file_system[*new_entry_index].block_type = MFS_BLOCK_TYPE_DIR;      mfs_file_system[*new_entry_index].u.dir_data.num_entries = 2;      mfs_file_system[*new_entry_index].u.dir_data.num_deleted = 0;      mfs_file_system[*new_entry_index].u.dir_data.dir_ent[0].index = parent_dir_block; /* parent dir of this new dir */      strcpy(mfs_file_system[*new_entry_index].u.dir_data.dir_ent[0].name, "..");      mfs_file_system[*new_entry_index].u.dir_data.dir_ent[0].deleted = 'n';      mfs_file_system[*new_entry_index].u.dir_data.dir_ent[1].index = *new_entry_index;      strcpy(mfs_file_system[*new_entry_index].u.dir_data.dir_ent[1].name, ".");      mfs_file_system[*new_entry_index].u.dir_data.dir_ent[1].deleted = 'n';      return 1;    }    else if (file_type == MFS_BLOCK_TYPE_FILE) {      mfs_file_system[*new_entry_index].block_type = MFS_BLOCK_TYPE_FILE;      mfs_file_system[*new_entry_index].block_size = 0; /* empty file */      return 1;    }    else { /* unknown file_type - error */      return 0;    }  }  return 0;}/** * return a pointer to the first char that follows the last '/' in filename * unless the last char in filename is a '/', in which case return a pointer  * to the first char that follows the previous '/' * if there is no '/' in filename, return filename itself */static char *get_basename(const char *filename) {   char *base_filename = (char*)filename;      while(*filename != '\0') {      if (*filename == '/') {         filename++;         if (*filename != '\0')            base_filename = (char*)filename; /* the first char after / */      }      else         filename++;   }   return base_filename;}/** * special strcpy for filename that omits the final '/' in the stored file name * return 2 if final '/' is seen * return 1 otherwise */static int set_filename(char *to_name, char *from_name) {  while (*from_name != '\0') {    if (*from_name == '/') {      *to_name = '\0';      return 2;    }    *to_name = *from_name;    to_name++;    from_name++;  }  *to_name = '\0';  return 1;}/** * return the first directory block corresponding to this directory block * the first directory block contains info about the number of files in the dir */static int get_first_dir_block(int dir_block) {  while(mfs_file_system[dir_block].prev_block != 0) {    dir_block = mfs_file_system[dir_block].prev_block;  }  return dir_block;}/** * Create a new file or dir  named filename * If a dir or file of the same name exists, return 0 * If there is no space on the file system to create file, return 0 * else create the new file or dir, add entry in current dir table  * and return index of first block of file or dir  */static int create_file(const char *filename, int file_type) {  int new_dir_block;  int new_dir_index;  int new_entry_index;  int new_block;  int first_dir_block;  if (get_dir_ent(filename, &new_dir_block, &new_dir_index)) {     /* file already exists */    return 0 ; /* cannot create file if it already exists */  }  else if (new_dir_block == -1 || new_dir_index == -1) {    /* file does not exist but path prefix does not exist either */    return 0; /* cannot create file because its parent dir does not exist */  }  else { /* create the file */    /* first check if the current dir block is full and        allocate a new dir block if needed */     if (new_dir_index == MFS_MAX_LOCAL_ENT) {       /* create a new dir block linked from this one */      if (get_next_free_block(&new_block)) { /* found a free block */	mfs_file_system[new_block].prev_block = new_dir_block;	mfs_file_system[new_block].next_block = 0;	mfs_file_system[new_block].block_type = MFS_BLOCK_TYPE_DIR;	mfs_file_system[new_block].u.dir_data.num_entries = 0;	mfs_file_system[new_block].u.dir_data.num_deleted = 0;	mfs_file_system[new_dir_block].next_block = new_block;	new_dir_block = new_block;	new_dir_index = 0;      }      else { /* no space for new block  - return failure */	return 0;      }    }    /* at this point new_dir_index and new_dir_block both point to        the first free entry */    first_dir_block = get_first_dir_block(new_dir_block);    if (!create_new_file(file_type, &new_entry_index, first_dir_block)) { /* cannot create new file */      return 0; /* failure */    };    /* update number of entries in current block */    mfs_file_system[new_dir_block].u.dir_data.num_entries += 1;    /* update number of entries in directory if it is different than current block */

⌨️ 快捷键说明

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