📄 fat_sup.c
字号:
count = node->size - node->offset; while ( count > 0 ) { if ( (node->type == FAT_FILE) && (node->offset >= node->size) ) { return moved; } /* Read requested sector if needed */ if ( (node->offset >= node->cache_offset + SECTORSIZE) || (node->offset < node->cache_offset) || (node->cache_offset < 0)) { status = node->parent ? read_block(node, node->geometry, offset): read_root_block(node, node->geometry, offset); if (status) { return -1; } offset += SECTORSIZE; } /* How many bytes are going to be read from the current sector */ bytes = (count < (SECTORSIZE - byte_offset)) ? count: (SECTORSIZE - byte_offset); /* Transfer them to cache */ memcpy (buffer+buffer_offset, node->cache + byte_offset, bytes); buffer_offset += bytes; byte_offset += bytes; byte_offset &= 0x1ff; count -= bytes; node->offset += bytes; moved += bytes; } /* end while */ return moved;}/* Writes a block from disk */intwrite_root_block(FAT_jnode_t *node, fat_geom_t *geom){ int disk_offset; int offset; int fd = geom->fd; /* check block alignment */ if (node->cache_offset < 0) node->cache_offset = 0; offset = node->cache_offset - node->cache_offset % SECTORSIZE; disk_offset = geom->root_dir_offset + offset; if (disk_offset >= geom->data_offset) return -1; lseek(fd,disk_offset,SEEK_SET); write(fd,node->cache,SECTORSIZE); return 0;}/*------------------------------------------------------------------- * Writes block to disk */intwrite_block(FAT_jnode_t *node, fat_geom_t *geom){ int cluster = node->current_cluster; int disk_offset; int fd = geom->fd; int offset; /* check block alignment */ if (node->cache_offset < 0) node->cache_offset = 0; offset = node->cache_offset - node->cache_offset % SECTORSIZE; disk_offset = cluster * geom->cluster_size + geom->first_cluster_offset + offset % geom->cluster_size; lseek(fd,disk_offset,SEEK_SET); write(fd,node->cache,SECTORSIZE); return 0;}/*------------------------------------------------------------------- * Not optimized fat write. It reads byte by byte and does not handle * errors */intfat_write (FAT_jnode_t *node, const char *buffer, int count){ int moved = 0; int status, read_sector, cluster = 0; int byte_offset, sector_offset, bytes; while (count > 0) { byte_offset = node->offset & 0x1ff; sector_offset = node->offset & 0xfffffe00; read_sector = 1; bytes = count > SECTORSIZE ? SECTORSIZE : count; /* Write less than one sector */ bytes = (bytes + byte_offset) > SECTORSIZE ? SECTORSIZE - byte_offset: bytes; if ( (node->offset + bytes > node->size) && (node->type == FAT_FILE) ) { if (node->size == 0) { /* New file */ /* printf("Archivo nuevo\n"); */ node->cache_offset = 0; node->current_cluster = node->st_ino; read_sector = 0; } else if ( (node->size % SECTORSIZE) !=0 ) { /* Room in the sector */ /* Do nothing */ /* printf("Hay espacio en el sector\n"); */ } else if ( (node->size % node->geometry->cluster_size) != 0 ) { /* Room in the cluster */ /* printf("Hay espacio en el cluster\n"); */ if (node->cache_offset != sector_offset) { find_cluster(node,sector_offset,&node->current_cluster); } node->cache_offset = sector_offset; byte_offset = 0; /* No need to read the sector because it is empty */ read_sector = 0; } else { /* File must grow */ /* printf("El archivo debe crecer\n"); */ if (find_cluster(node,sector_offset,&node->current_cluster) < 0) { rtems_semaphore_obtain( node->geometry->mutex_id, RTEMS_WAIT,RTEMS_NO_TIMEOUT ); cluster = search_free_cluster(node->geometry); /* printf("cluster actual: %d\n",node->current_cluster); printf("nuevo cluster: %d\n",cluster); */ if (cluster < 2) { /* No room in disk */ rtems_semaphore_release( node->geometry->mutex_id ); return moved; } add_cluster(node->current_cluster, cluster, node->geometry); rtems_semaphore_release( node->geometry->mutex_id ); } read_sector = 0; /* New cluster is empty */ node->cache_offset = sector_offset; node->current_cluster = cluster; byte_offset = 0; } node->size += bytes; } else { } if (read_sector) { status = node->parent ? read_block(node, node->geometry, sector_offset): read_root_block(node, node->geometry, sector_offset); } memcpy(node->cache+byte_offset,buffer+moved,bytes); status = node->parent ? write_block(node, node->geometry): write_root_block(node, node->geometry); count -= bytes; moved += bytes; node->offset += bytes; } /* end while */ return moved;}/*------------------------------------------------------------------- * After any change (write or truncate) in a FAT file, directory * entry must be updated. */intupdate_dir_entry(FAT_jnode_t *node){ FAT_jnode_t *parent = node->parent; unsigned char buffer[32]; int j, k; rtems_time_of_day tod; unsigned short date; unsigned short time; if (node->type != FAT_FILE) return 0; if (parent) { memset(buffer,0,32); memset(buffer,0x20,11); rtems_clock_get(RTEMS_CLOCK_GET_TOD, &tod); for (j=0, k=0; node->name[j] != 0; j++) { if (node->name[j] == '.') { k = 8; continue; } buffer[k++] = upchar(node->name[j]); }; buffer[11] = 0x20; /* Normal file */ time = (tod.hour << 11) + (tod.minute << 5) + (tod.second / 2); date = ((tod.year - 1980) << 9) + (tod.month << 5) + tod.day; *(unsigned short *)(buffer+22) = time; *(unsigned short *)(buffer+24) = date; *(unsigned short *)(buffer+26) = node->st_ino; *(unsigned *)(buffer+28) = node->size; parent->offset = node->dir_offset; fat_write(parent, buffer, 32); } else { } return 0;}/*------------------------------------------------------------------- * */FAT_jnode_t *FAT_find_match_in_dir(const char *token, FAT_jnode_t *parent){ FAT_jnode_t *index; unsigned char buffer[sizeof(struct dirent)]; index = fat_root_dir; while (index) { if (index->parent == parent) { if (!strcmp(token,index->name)) { return index; } } index = index->next; } if (!index) { /* If the node does not exist, find it * and create a new one */ parent->offset = 0; index = (FAT_jnode_t *)calloc(1, sizeof(FAT_jnode_t)); if (!index) return NULL; while (fat_dir_read( parent, buffer,sizeof(struct dirent), index ) > 0) { if (strcmp(token, index->name) == 0) { /* printf("%s %s\n",token,index->name); */ index->cache_offset = -1; index->offset = 0; index->current_cluster = index->st_ino; add_node(index); return index; } }; free(index); return NULL; } return index;}inline intFAT_Set_handlers( rtems_filesystem_location_info_t *loc ){ FAT_jnode_t *node = loc->node_access; switch( node->type ) { case FAT_DIRECTORY: loc->handlers = &FAT_directory_handlers; break; case FAT_FILE: loc->handlers = &FAT_file_handlers; break; default: loc->handlers = NULL; return -1; break; } return 0;}FAT_token_typesFAT_get_token( const char *path, char *token, int *token_len ){ register int i = 0; FAT_token_types type = FAT_NAME; register char c; /* * Copy a name into token. (Remember NULL is a token.) */ c = path[i]; while ( (c != '/') && (c != '\0') && (i <= FAT_NAME_MAX+1) ) { token[i] = c; if ( i > (FAT_NAME_MAX+1) ) return FAT_INVALID_TOKEN; if ( fat_is_not_valid_char(c) ) type = FAT_INVALID_TOKEN; c = path [++i]; } /* * Copy a seperator into token. */ if ( i == 0 ) { token[i] = c; if ( token[i] != '\0' ) { i++; type = FAT_CURRENT_DIR; } else { type = FAT_NO_MORE_PATH; } } else if (token[ i-1 ] != '\0') { token[i] = '\0'; } /* * Set token_len to the number of characters copied. */ *token_len = i; /* * If we copied something that was not a seperator see if * it was a special name. */ if ( type == FAT_NAME ) { if ( strcmp( token, "..") == 0 ) type = FAT_UP_DIR; else if ( strcmp( token, "." ) == 0 ) type = FAT_CURRENT_DIR; } return type;}/* * FAT_evaluate_for_make * * The following routine evaluate path for a new node to be created. * pathloc is returned with a pointer to the parent of the new node. * name is returned with a pointer to the first character in the * new node name. The parent node is verified to be a directory. */intFAT_evaluate_for_make(path, pathloc, name) const char *path; /* IN */ rtems_filesystem_location_info_t *pathloc; /* IN/OUT */ const char **name; /* OUT */{ int i = 0; int len; FAT_token_types type; char token[ 14 ]; rtems_filesystem_location_info_t newloc; FAT_jnode_t *node; int done = 0; int result; /* * This was filled in by the caller and is valid in the * mount table. */ node = pathloc->node_access; /* * Evaluate all tokens until we are done or an error occurs. */ while( !done ) { type = FAT_get_token( &path[i], token, &len ); i += len; if ( !pathloc->node_access ) set_errno_and_return_minus_one( ENOENT ); node = pathloc->node_access; switch( type ) { case FAT_UP_DIR: /* * Am I at the root of this mounted filesystem? */ if (pathloc->node_access == pathloc->mt_entry->mt_fs_root.node_access) { newloc = pathloc->mt_entry->mt_point_node; *pathloc = newloc; return (*pathloc->ops->evalformake)( &path[i-len], pathloc, name ); } else { if ( !node->parent ) set_errno_and_return_minus_one( ENOENT ); node = node->parent;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -