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

📄 fs_fat32.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
📖 第 1 页 / 共 4 页
字号:
 * ****************************************************************************/static int fat_unlink(struct inode *mountpt, const char *relpath){  struct fat_mountpt_s *fs;  int                   ret;  /* Sanity checks */  DEBUGASSERT(mountpt && mountpt->i_private);  /* Get the mountpoint private data from the inode structure */  fs = mountpt->i_private;  /* Check if the mount is still healthy */  fat_semtake(fs);  ret = fat_checkmount(fs);  if (ret == OK)    {      /* If the file is open, the correct behavior is to remove the file       * name, but to keep the file cluster chain in place until the last       * open reference to the file is closed.       */#warning "Need to defer deleting cluster chain if the file is open"      /* Remove the file */      ret = fat_remove(fs, relpath, FALSE);    }  fat_semgive(fs);  return ret;}/**************************************************************************** * Name: fat_mkdir * * Description: Create a directory * ****************************************************************************/static int fat_mkdir(struct inode *mountpt, const char *relpath, mode_t mode){  struct fat_mountpt_s *fs;  struct fat_dirinfo_s  dirinfo;  ubyte       *direntry;  ubyte       *direntry2;  size_t       parentsector;  ssize_t      dirsector;  sint32       dircluster;  uint32       parentcluster;  uint32       crtime;  unsigned int i;  int          ret;  /* Sanity checks */  DEBUGASSERT(mountpt && mountpt->i_private);  /* Get the mountpoint private data from the inode structure */  fs = mountpt->i_private;  /* Check if the mount is still healthy */  fat_semtake(fs);  ret = fat_checkmount(fs);  if (ret != OK)    {      goto errout_with_semaphore;    }  /* Find the directory where the new directory should be created. */  ret = fat_finddirentry(fs, &dirinfo, relpath);  /* If anything exists at this location, then we fail with EEXIST */  if (ret == OK)    {      ret = -EEXIST;      goto errout_with_semaphore;    }  /* What we want to see is for fat_finddirentry to fail with -ENOENT.   * This error means that no failure occurred but that nothing exists   * with this name.   */  if (ret != -ENOENT)    {      goto errout_with_semaphore;    }  /* NOTE: There is no check that dirinfo.fd_name contains the final   * directory name.  We could be creating an intermediate directory   * in the full relpath.   */  /* Allocate a directory entry for the new directory in this directory */  ret = fat_allocatedirentry(fs, &dirinfo);  if (ret != OK)    {      goto errout_with_semaphore;    }  parentsector = fs->fs_currentsector;  /* Allocate a cluster for new directory */  dircluster = fat_createchain(fs);  if (dircluster < 0)    {      ret = dircluster;      goto errout_with_semaphore;    }  else if (dircluster < 2)    {      ret = -ENOSPC;      goto errout_with_semaphore;    }  dirsector = fat_cluster2sector(fs, dircluster);  if (dirsector < 0)    {      ret = dirsector;      goto errout_with_semaphore;    }  /* Flush any existing, dirty data in fs_buffer (because we need    * it to create the directory entries.   */  ret = fat_fscacheflush(fs);  if (ret < 0)    {      goto errout_with_semaphore;    }  /* Get a pointer to the first directory entry in the sector */  direntry = fs->fs_buffer;  /* Now erase the contents of fs_buffer */  fs->fs_currentsector = dirsector;  memset(direntry, 0, fs->fs_hwsectorsize);  /* Now clear all sectors in the new directory cluster (except for the first) */  for (i = 1; i < fs->fs_fatsecperclus; i++)    {      ret = fat_hwwrite(fs, direntry, ++dirsector, 1);      if (ret < 0)        {          goto errout_with_semaphore;        }    }  /* Now create the "." directory entry in the first directory slot */  memset(&direntry[DIR_NAME], ' ', 8+3);  direntry[DIR_NAME] = '.';  DIR_PUTATTRIBUTES(direntry, FATATTR_DIRECTORY);  crtime = fat_systime2fattime();  DIR_PUTCRTIME(direntry, crtime & 0xffff);  DIR_PUTWRTTIME(direntry, crtime & 0xffff);  DIR_PUTCRDATE(direntry, crtime >> 16);  DIR_PUTWRTDATE(direntry, crtime >> 16);  /* Create ".." directory entry in the second directory slot */  direntry2 = direntry + 32;  /* So far, the two entries are nearly the same */  memcpy(direntry2, direntry, 32);  direntry2[DIR_NAME+1] = '.';  /* Now add the cluster information to both directory entries */  DIR_PUTFSTCLUSTHI(direntry, dircluster >> 16);  DIR_PUTFSTCLUSTLO(direntry, dircluster);  parentcluster = dirinfo.dir.fd_startcluster;  if (fs->fs_type != FSTYPE_FAT32 && parentcluster == fs->fs_rootbase)    {      parentcluster = 0;    }  DIR_PUTFSTCLUSTHI(direntry2, parentcluster >> 16);  DIR_PUTFSTCLUSTLO(direntry2, parentcluster);  /* Save the first sector of the directory cluster and re-read   *  the parentsector   */  fs->fs_dirty = TRUE;  ret = fat_fscacheread(fs, parentsector);  if (ret < 0)    {      goto errout_with_semaphore;    }  /* Initialize the new entry directory entry in the parent directory */  direntry = dirinfo.fd_entry;  memset(direntry, 0, 32);  memcpy(direntry, dirinfo.fd_name, 8+3);#ifdef CONFIG_FLAT_LCNAMES  DIR_PUTNTRES(direntry, dirinfo.fd_ntflags);#endif  DIR_PUTATTRIBUTES(dirinfo.fd_entry, FATATTR_DIRECTORY);  /* Same creation time as for . and .. */  DIR_PUTCRTIME(dirinfo.fd_entry, crtime & 0xffff);  DIR_PUTWRTTIME(dirinfo.fd_entry, crtime & 0xffff);  DIR_PUTCRDATE(dirinfo.fd_entry, crtime >> 16);  DIR_PUTWRTDATE(dirinfo.fd_entry, crtime >> 16);  /* Set subdirectory start cluster */  DIR_PUTFSTCLUSTLO(dirinfo.fd_entry, dircluster);  DIR_PUTFSTCLUSTHI(dirinfo.fd_entry, dircluster >> 16);  /* Now update the FAT32 FSINFO sector */  fs->fs_dirty = TRUE;  ret = fat_updatefsinfo(fs);  if (ret < 0)    {      goto errout_with_semaphore;    }  fat_semgive(fs);  return OK;errout_with_semaphore:  fat_semgive(fs);  return ret;}/**************************************************************************** * Name: fat_rmdir * * Description: Remove a directory * ****************************************************************************/int fat_rmdir(struct inode *mountpt, const char *relpath){  struct fat_mountpt_s *fs;  int                   ret;  /* Sanity checks */  DEBUGASSERT(mountpt && mountpt->i_private);  /* Get the mountpoint private data from the inode structure */  fs = mountpt->i_private;  /* Check if the mount is still healthy */  fat_semtake(fs);  ret = fat_checkmount(fs);  if (ret == OK)    {      /* If the directory is open, the correct behavior is to remove the directory       * name, but to keep the directory cluster chain in place until the last       * open reference to the directory is closed.       */#warning "Need to defer deleting cluster chain if the directory is open"      /* Remove the directory */      ret = fat_remove(fs, relpath, TRUE);    }  fat_semgive(fs);  return ret;}/**************************************************************************** * Name: fat_rename * * Description: Rename a file or directory * ****************************************************************************/int fat_rename(struct inode *mountpt, const char *oldrelpath,               const char *newrelpath){  struct fat_mountpt_s *fs;  struct fat_dirinfo_s  dirinfo;  size_t                oldsector;  ubyte                *olddirentry;  ubyte                *newdirentry;  ubyte                 dirstate[32-11];  int                   ret;  /* Sanity checks */  DEBUGASSERT(mountpt && mountpt->i_private);  /* Get the mountpoint private data from the inode structure */  fs = mountpt->i_private;  /* Check if the mount is still healthy */  fat_semtake(fs);  ret = fat_checkmount(fs);  if (ret != OK)    {      goto errout_with_semaphore;    }  /* Find the directory entry for the oldrelpath */  ret = fat_finddirentry(fs, &dirinfo, oldrelpath);  if (ret != OK)    {      /* Some error occurred -- probably -ENOENT */      goto errout_with_semaphore;    }  /* Save the information that will need to recover the   * directory sector and directory entry offset to the   * old directory.   */  olddirentry = dirinfo.fd_entry;  /* One more check:  Make sure that the oldrelpath does   * not refer to the root directory.  We can't rename the   * root directory.   */  if (!olddirentry)    {      ret = -EXDEV;      goto errout_with_semaphore;    }  oldsector   = fs->fs_currentsector;  memcpy(dirstate, &olddirentry[DIR_ATTRIBUTES], 32-11);  /* No find the directory where we should create the newpath object */  ret = fat_finddirentry(fs, &dirinfo, newrelpath);  if (ret == OK)    {      /* It is an error if the object at newrelpath already exists */      ret = -EEXIST;      goto errout_with_semaphore;    }  /* What we expect is -ENOENT mean that the full directory path was   * followed but that the object does not exists in the terminal directory.   */  if (ret != -ENOENT)    {      goto errout_with_semaphore;    }  /* Reserve a directory entry */  ret = fat_allocatedirentry(fs, &dirinfo);  if (ret != OK)    {      goto errout_with_semaphore;    }  /* Create the new directory entry */  newdirentry = dirinfo.fd_entry;  memcpy(&newdirentry[DIR_ATTRIBUTES], dirstate, 32-11);  memcpy(&newdirentry[DIR_NAME], dirinfo.fd_name, 8+3);#ifdef CONFIG_FLAT_LCNAMES  DIR_PUTNTRES(newdirentry, dirinfo.fd_ntflags);#else  DIR_PUTNTRES(newdirentry, 0);#endif  fs->fs_dirty = TRUE;  /* Now flush the new directory entry to disk and read the sector   * containing the old directory entry.   */  ret = fat_fscacheread(fs, oldsector);  if (ret < 0)    {      goto errout_with_semaphore;    }  /* Remove the old entry */  olddirentry[DIR_NAME] = DIR0_EMPTY;  fs->fs_dirty = TRUE;  /* Write the old entry to disk and update FSINFO if necessary */  ret = fat_updatefsinfo(fs);  if (ret < 0)    {      goto errout_with_semaphore;    }  fat_semgive(fs);  return OK;errout_with_semaphore:  fat_semgive(fs);  return ret;}/**************************************************************************** * Name: fat_stat * * Description: Return information about a file or directory * ****************************************************************************/static int fat_stat(struct inode *mountpt, const char *relpath, struct stat *buf){  struct fat_mountpt_s *fs;  struct fat_dirinfo_s  dirinfo;  uint16                date;  uint16                date2;  uint16                time;  ubyte                 attribute;  int                   ret;  /* Sanity checks */  DEBUGASSERT(mountpt && mountpt->i_private);  /* Get the mountpoint private data from the inode structure */  fs = mountpt->i_private;  /* Check if the mount is still healthy */  fat_semtake(fs);  ret = fat_checkmount(fs);  if (ret != OK)    {      goto errout_with_semaphore;    }  /* Find the directory entry corresponding to relpath. */  ret = fat_finddirentry(fs, &dirinfo, relpath);  /* If nothing was found, then we fail with EEXIST */  if (ret < 0)    {      goto errout_with_semaphore;    }  memset(buf, 0, sizeof(struct stat));  if (!dirinfo.fd_entry)    {      /* It's directory name of mount point */      buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR|S_IWOTH|S_IWGRP|S_IWUSR;      ret = OK;      goto errout_with_semaphore;    }  /* Get the FAT attribute and map it so some meaningful mode_t values */  attribute = DIR_GETATTRIBUTES(dirinfo.fd_entry);  if ((attribute & FATATTR_VOLUMEID) != 0)    {      ret = -ENOENT;      goto errout_with_semaphore;    }  /* Set the access permissions.  The file/directory is always readable   * by everyone but may be writeable by no-one.   */  buf->st_mode = S_IROTH|S_IRGRP|S_IRUSR;  if ((attribute & FATATTR_READONLY) == 0)    {      buf->st_mode |= S_IWOTH|S_IWGRP|S_IWUSR;    }  /* We will report only types file or directory */  if ((attribute & FATATTR_DIRECTORY) != 0)    {      buf->st_mode |= S_IFDIR;    }  else    {      buf->st_mode |= S_IFREG;    }  /* File/directory size, access block size */  buf->st_size      = DIR_GETFILESIZE(dirinfo.fd_entry);  buf->st_blksize   = fs->fs_fatsecperclus * fs->fs_hwsectorsize;  buf->st_blocks    = (buf->st_size + buf->st_blksize - 1) / buf->st_blksize;  /* Times */  date              = DIR_GETWRTDATE(dirinfo.fd_entry);  time              = DIR_GETWRTTIME(dirinfo.fd_entry);  buf->st_mtime     = fat_fattime2systime(time, date);  date2             = DIR_GETLASTACCDATE(dirinfo.fd_entry);  if (date == date2)    {      buf->st_atime = buf->st_mtime;    }  else    {      buf->st_atime = fat_fattime2systime(0, date2);    }  date              = DIR_GETCRDATE(dirinfo.fd_entry);  time              = DIR_GETCRTIME(dirinfo.fd_entry);  buf->st_ctime     = fat_fattime2systime(time, date);  ret = OK;errout_with_semaphore:  fat_semgive(fs);  return ret;}/**************************************************************************** * Public Functions ****************************************************************************/

⌨️ 快捷键说明

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