📄 msdos_misc.c
字号:
/* update node_info_ptr field */ parent_loc->node_access = fat_fd; return rc;} /* msdos_get_name_node -- * This routine is used in two ways: for a new mode creation (a) or for * search the node which correspondes to the name parameter (b). * In case (a) 'name' should be set up to NULL and 'name_dir_entry' should * point to initialized 32 bytes structure described a new node. * In case (b) 'name' should contain a valid string. * * (a): reading fat-file which correspondes to directory we are going to * create node in. If free slot is found write contents of * 'name_dir_entry' into it. If reach end of fat-file and no free * slot found, write 32 bytes to the end of fat-file. * * (b): reading fat-file which correspondes to directory and trying to * find slot with the name field == 'name' parameter * * * PARAMETERS: * parent_loc - node description to create node in or to find name in * name - NULL or name to find * paux - identify a node location on the disk - * cluster num and offset inside the cluster * name_dir_entry - node to create/placeholder for found node (IN/OUT) * * RETURNS: * RC_OK, filled aux_struct_ptr and name_dir_entry on success, or -1 if * error occured (errno set apropriately) * */intmsdos_get_name_node( rtems_filesystem_location_info_t *parent_loc, char *name, fat_auxiliary_t *paux, char *name_dir_entry ){ int rc = RC_OK; ssize_t ret = 0; msdos_fs_info_t *fs_info = parent_loc->mt_entry->fs_info; fat_file_fd_t *fat_fd = parent_loc->node_access; unsigned32 dotdot_cln = 0; /* find name in fat-file which correspondes to the directory */ rc = msdos_find_name_in_fat_file(parent_loc->mt_entry, fat_fd, name, paux, name_dir_entry); if ((rc != RC_OK) && (rc != MSDOS_NAME_NOT_FOUND_ERR)) return rc; /* if we search for valid name and name not found -> return */ if ((rc == MSDOS_NAME_NOT_FOUND_ERR) && (name != NULL)) return rc; /* * if we try to create new entry and the directory is not big enough * currently - try to enlarge directory */ if ((rc == MSDOS_NAME_NOT_FOUND_ERR) && (name == NULL)) { ret = fat_file_write(parent_loc->mt_entry, fat_fd, fat_fd->fat_file_size, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE, name_dir_entry); if (ret == -1) return -1; /* on success directory is enlarged by a new cluster */ fat_fd->fat_file_size += fs_info->fat.vol.bpc; /* get cluster num where a new node located */ rc = fat_file_ioctl(parent_loc->mt_entry, fat_fd, F_CLU_NUM, fat_fd->fat_file_size - 1, &paux->cln); if (rc != RC_OK) return rc; /* * if new cluster allocated succesfully then new node is at very * beginning of the cluster (offset is computed in bytes) */ paux->ofs = 0; return RC_OK; } /* * if we have deal with ".." - it is a special case :((( * * Really, we should return cluster num and offset not of ".." slot, but * slot which correspondes to real directory name. */ if ((rc == RC_OK) && (name != NULL)) { if (strncmp(name, MSDOS_DOTDOT_NAME, MSDOS_SHORT_NAME_LEN) == 0) { dotdot_cln = MSDOS_EXTRACT_CLUSTER_NUM((name_dir_entry)); /* are we right under root dir ? */ if (dotdot_cln == 0) { /* * we can relax about first_char field - it never should be * used for root dir */ paux->cln = FAT_ROOTDIR_CLUSTER_NUM; paux->ofs = 0; } else { rc = msdos_get_dotdot_dir_info_cluster_num_and_offset( parent_loc->mt_entry, dotdot_cln, paux, name_dir_entry ); if (rc != RC_OK) return rc; } } } return rc;}/* * msdos_get_dotdot_dir_info_cluster_num_and_offset * * Unfortunately, in general, we cann't work here in fat-file ideologic * (open fat_file "..", get ".." and ".", open "..", find an entry ...) * because if we open * fat-file ".." it may happend that we have two different fat-file * descriptors ( for real name of directory and ".." name ) for a single * file ( cluster num of both pointers to the same cluster ) * But...we do it because we protected by semaphore * *//* msdos_get_dotdot_dir_info_cluster_num_and_offset -- * Get cluster num and offset not of ".." slot, but slot which correspondes * to real directory name. * * PARAMETERS: * mt_entry - mount table entry * cln - data cluster num extracted drom ".." slot * paux - identify a node location on the disk - * number of cluster and offset inside the cluster * dir_entry - placeholder for found node * * RETURNS: * RC_OK, filled 'paux' and 'dir_entry' on success, or -1 if error occured * (errno set apropriately) * */intmsdos_get_dotdot_dir_info_cluster_num_and_offset( rtems_filesystem_mount_table_entry_t *mt_entry, unsigned32 cln, fat_auxiliary_t *paux, char *dir_entry ){ int rc = RC_OK; msdos_fs_info_t *fs_info = mt_entry->fs_info; fat_file_fd_t *fat_fd = NULL; unsigned char dot_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE]; unsigned char dotdot_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE]; unsigned char cur_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE]; unsigned32 cl4find = 0; memset(dot_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); memset(dotdot_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); memset(cur_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); /* * open fat-file corresponded to ".." */ rc = fat_file_open(mt_entry, paux->cln, paux->ofs, &fat_fd); if (rc != RC_OK) return rc; fat_fd->info_cln = paux->cln; fat_fd->info_ofs = paux->ofs; fat_fd->cln = cln; fat_fd->fat_file_type = FAT_DIRECTORY; fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT; fat_fd->map.file_cln = 0; fat_fd->map.disk_cln = fat_fd->cln; rc = fat_file_size(mt_entry, fat_fd); if (rc != RC_OK) { fat_file_close(mt_entry, fat_fd); return rc; } /* find "." node in opened directory */ rc = msdos_find_name_in_fat_file(mt_entry, fat_fd, MSDOS_DOT_NAME, paux, dot_node); if (rc != RC_OK) { fat_file_close(mt_entry, fat_fd); return rc; } /* find ".." node in opened directory */ rc = msdos_find_name_in_fat_file(mt_entry, fat_fd, MSDOS_DOTDOT_NAME, paux, dotdot_node); if (rc != RC_OK) { fat_file_close(mt_entry, fat_fd); return rc; } cl4find = MSDOS_EXTRACT_CLUSTER_NUM(dot_node); /* close fat-file corresponded to ".." directory */ rc = fat_file_close(mt_entry, fat_fd); if ( rc != RC_OK ) return rc; if ( (MSDOS_EXTRACT_CLUSTER_NUM(dotdot_node)) == 0) { /* * we handle root dir for all FAT types in the same way with the * ordinary directories ( through fat_file_* calls ) */ paux->cln = FAT_ROOTDIR_CLUSTER_NUM; paux->ofs = 0; } /* open fat-file corresponded to second ".." */ rc = fat_file_open(mt_entry, paux->cln, paux->ofs, &fat_fd); if (rc != RC_OK) return rc; fat_fd->info_cln = paux->cln; fat_fd->info_ofs = paux->ofs; if ((MSDOS_EXTRACT_CLUSTER_NUM(dotdot_node)) == 0) fat_fd->cln = fs_info->fat.vol.rdir_cl; else fat_fd->cln = MSDOS_EXTRACT_CLUSTER_NUM(dotdot_node); fat_fd->fat_file_type = FAT_DIRECTORY; fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT; fat_fd->map.file_cln = 0; fat_fd->map.disk_cln = fat_fd->cln; rc = fat_file_size(mt_entry, fat_fd); if (rc != RC_OK) { fat_file_close(mt_entry, fat_fd); return rc; } /* in this directory find slot with specified cluster num */ rc = msdos_find_node_by_cluster_num_in_fat_file(mt_entry, fat_fd, cl4find, paux, dir_entry); if (rc != RC_OK) { fat_file_close(mt_entry, fat_fd); return rc; } rc = fat_file_close(mt_entry, fat_fd); return rc;}/* msdos_set_dir_wrt_time_and_date -- * Write last write date and time for a file to the disk (to corresponded * 32bytes node) * * PARAMETERS: * mt_entry - mount table entry * fat_fd - fat-file descriptor * * RETURNS: * RC_OK on success, or -1 if error occured (errno set apropriately). * */intmsdos_set_dir_wrt_time_and_date( rtems_filesystem_mount_table_entry_t *mt_entry, fat_file_fd_t *fat_fd ){ ssize_t ret1 = 0, ret2 = 0; msdos_fs_info_t *fs_info = mt_entry->fs_info; unsigned short time_val; unsigned short date; unsigned32 sec = 0; unsigned32 byte = 0; msdos_date_unix2dos(fat_fd->mtime, &time_val, &date); /* * calculate input for _fat_block_write: convert (cluster num, offset) to * (sector num, new offset) */ sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->info_cln); sec += (fat_fd->info_ofs >> fs_info->fat.vol.sec_log2); /* byte points to start of 32bytes structure */ byte = fat_fd->info_ofs & (fs_info->fat.vol.bps - 1); time_val = CT_LE_W(time_val); ret1 = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_WTIME_OFFSET, 2, (char *)(&time_val)); date = CT_LE_W(date); ret2 = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_WDATE_OFFSET, 2, (char *)(&date)); if ( (ret1 < 0) || (ret2 < 0) ) return -1; return RC_OK;}/* msdos_set_first_cluster_num -- * Write number of first cluster of the file to the disk (to corresponded * 32bytes slot) * * PARAMETERS: * mt_entry - mount table entry * fat_fd - fat-file descriptor * * RETURNS: * RC_OK on success, or -1 if error occured * */intmsdos_set_first_cluster_num( rtems_filesystem_mount_table_entry_t *mt_entry, fat_file_fd_t *fat_fd ){ ssize_t ret1 = 0, ret2 = 0; msdos_fs_info_t *fs_info = mt_entry->fs_info; unsigned32 new_cln = fat_fd->cln; unsigned16 le_cl_low = 0; unsigned16 le_cl_hi = 0; unsigned32 sec = 0; unsigned32 byte = 0; /* * calculate input for _fat_block_write: convert (cluster num, offset) to * (sector num, new offset) */ sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->info_cln); sec += (fat_fd->info_ofs >> fs_info->fat.vol.sec_log2); /* byte from points to start of 32bytes structure */ byte = fat_fd->info_ofs & (fs_info->fat.vol.bps - 1); le_cl_low = CT_LE_W((unsigned16)(new_cln & 0x0000FFFF)); ret1 = _fat_block_write(mt_entry, sec,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -