📄 msdos_dir.c
字号:
* * unfortunately there is no method to extract ino except to * open fat-file descriptor :( ... so, open it */ /* get number of cluster we are working with */ rc = fat_file_ioctl(iop->pathinfo.mt_entry, fat_fd, F_CLU_NUM, j * bts2rd, &cur_cln); if (rc != RC_OK) { rtems_semaphore_release(fs_info->vol_sema); return rc; } rc = fat_file_open(iop->pathinfo.mt_entry, cur_cln, i, &tmp_fat_fd); if (rc != RC_OK) { rtems_semaphore_release(fs_info->vol_sema); return rc; } tmp_fat_fd->info_cln = cur_cln; tmp_fat_fd->info_ofs = i; /* fill in dirent structure */ /* XXX: from what and in what d_off should be computed ?! */ tmp_dirent.d_off = start + cmpltd; tmp_dirent.d_reclen = sizeof(struct dirent); tmp_dirent.d_ino = tmp_fat_fd->ino; /* * convert dir entry from fixed 8+3 format (without dot) * to 0..8 + 1dot + 0..3 format */ tmp_dirent.d_namlen = msdos_format_dirent_with_dot(tmp_dirent.d_name, fs_info->cl_buf + i); /* src text */ memcpy(buffer + cmpltd, &tmp_dirent, sizeof(struct dirent)); iop->offset = iop->offset + sizeof(struct dirent); cmpltd += (sizeof(struct dirent)); count -= (sizeof(struct dirent)); /* inode number extracted, close fat-file */ rc = fat_file_close(iop->pathinfo.mt_entry, tmp_fat_fd); if (rc != RC_OK) { rtems_semaphore_release(fs_info->vol_sema); return rc; } if (count <= 0) break; } j++; } rtems_semaphore_release(fs_info->vol_sema); return cmpltd;}/* msdos_dir_write -- * no write for directory *//* msdos_dir_lseek -- * * This routine will behave in one of three ways based on the state of * argument whence. Based on the state of its value the offset argument will * be interpreted using one of the following methods: * * SEEK_SET - offset is the absolute byte offset from the start of the * logical start of the dirent sequence that represents the * directory * SEEK_CUR - offset is used as the relative byte offset from the current * directory position index held in the iop structure * SEEK_END - N/A --> This will cause an assert. * * PARAMETERS: * iop - file control block * offset - offset * whence - predefine directive * * RETURNS: * RC_OK on success, or -1 if error occured (errno * set apropriately). */int msdos_dir_lseek(rtems_libio_t *iop, off_t offset, int whence){ switch (whence) { case SEEK_SET: case SEEK_CUR: break; /* * Movement past the end of the directory via lseek is not a * permitted operation */ case SEEK_END: default: set_errno_and_return_minus_one( EINVAL ); break; } return RC_OK;}/* msdos_dir_stat -- * * This routine will obtain the following information concerning the current * directory: * st_dev device id * st_ino node serial number :) * st_mode mode extracted from the node * st_size total size in bytes * st_blksize blocksize for filesystem I/O * st_blocks number of blocks allocated * stat_mtime time of last modification * * PARAMETERS: * loc - this directory * buf - stat buffer provided by user * * RETURNS: * RC_OK and filled stat buffer on success, or -1 if error occured (errno * set apropriately). */int msdos_dir_stat( rtems_filesystem_location_info_t *loc, struct stat *buf ){ rtems_status_code sc = RTEMS_SUCCESSFUL; msdos_fs_info_t *fs_info = loc->mt_entry->fs_info; fat_file_fd_t *fat_fd = loc->node_access; sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, MSDOS_VOLUME_SEMAPHORE_TIMEOUT); if (sc != RTEMS_SUCCESSFUL) set_errno_and_return_minus_one(EIO); buf->st_dev = fs_info->fat.vol.dev; buf->st_ino = fat_fd->ino; buf->st_mode = S_IFDIR; buf->st_rdev = 0ll; buf->st_size = fat_fd->fat_file_size; buf->st_blocks = fat_fd->fat_file_size >> FAT_SECTOR512_BITS; buf->st_blksize = fs_info->fat.vol.bps; buf->st_mtime = fat_fd->mtime; rtems_semaphore_release(fs_info->vol_sema); return RC_OK;}/* msdos_dir_truncate -- * No truncate for directory. * * PARAMETERS: * * RETURNS: * *//* msdos_dir_sync -- * The following routine does a syncronization on a MSDOS directory node. * DIR_WrtTime, DIR_WrtDate and DIR_fileSize fields of 32 Bytes Directory * Entry Structure should not be updated for directories, so only call * to corresponding fat-file routine. * * PARAMETERS: * iop - file control block * * RETURNS: * RC_OK on success, or -1 if error occured (errno set apropriately). */intmsdos_dir_sync(rtems_libio_t *iop){ int rc = RC_OK; rtems_status_code sc = RTEMS_SUCCESSFUL; fat_file_fd_t *fat_fd = iop->file_info; msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, MSDOS_VOLUME_SEMAPHORE_TIMEOUT); if (sc != RTEMS_SUCCESSFUL) set_errno_and_return_minus_one(EIO); rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd); rtems_semaphore_release(fs_info->vol_sema); return rc;}/* msdos_dir_rmnod -- * Remove directory node. * * Check that this directory node is not opened as fat-file, is empty and * not filesystem root node. If all this conditions met then delete. * * PARAMETERS: * pathloc - node description * * RETURNS: * RC_OK on success, or -1 if error occured (errno set apropriately). */int msdos_dir_rmnod(rtems_filesystem_location_info_t *pathloc){ int rc = RC_OK; rtems_status_code sc = RTEMS_SUCCESSFUL; msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info; fat_file_fd_t *fat_fd = pathloc->node_access; rtems_boolean is_empty = FALSE; sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, MSDOS_VOLUME_SEMAPHORE_TIMEOUT); if (sc != RTEMS_SUCCESSFUL) set_errno_and_return_minus_one(EIO); /* * We deny attemp to delete open directory (if directory is current * directory we assume it is open one) */ if (fat_fd->links_num > 1) { rtems_semaphore_release(fs_info->vol_sema); set_errno_and_return_minus_one(EBUSY); } /* * You cannot remove a node that still has children */ rc = msdos_dir_is_empty(pathloc->mt_entry, fat_fd, &is_empty); if (rc != RC_OK) { rtems_semaphore_release(fs_info->vol_sema); return rc; } if (!is_empty) { rtems_semaphore_release(fs_info->vol_sema); set_errno_and_return_minus_one(ENOTEMPTY); } /* * You cannot remove the file system root node. */ if (pathloc->mt_entry->mt_fs_root.node_access == pathloc->node_access) { rtems_semaphore_release(fs_info->vol_sema); set_errno_and_return_minus_one(EBUSY); } /* * You cannot remove a mountpoint. * not used - mount() not implemenetd yet. */ /* mark file removed */ rc = msdos_set_first_char4file_name(pathloc->mt_entry, fat_fd->info_cln, fat_fd->info_ofs, MSDOS_THIS_DIR_ENTRY_EMPTY); if (rc != RC_OK) { rtems_semaphore_release(fs_info->vol_sema); return rc; } fat_file_mark_removed(pathloc->mt_entry, fat_fd); rtems_semaphore_release(fs_info->vol_sema); return rc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -