static void clear_cluster (PedFileSystem* fs, FatCluster cluster) { FatSpecific* fs_info = FAT_SPECIFIC (fs); memset (fs_info->buffer, 0, fs_info->cluster_size); fat_write_cluster (fs, fs_info->buffer, cluster); }
int fat_write_sync_cluster (PedFileSystem* fs, char *buf, FatCluster cluster) { if (!fat_write_cluster (fs, buf, cluster)) return 0; if (!ped_geometry_sync (fs->geom)) return 0; return 1; }
static int fatfs_mkdir(vnode_t dvp, char *name, mode_t mode) { struct fatfsmount *fmp; struct fatfs_node np; struct fat_dirent *de; u_long cl; int error; if (!S_ISDIR(mode)) return EINVAL; if (!fat_valid_name(name)) return ENOTDIR; fmp = dvp->v_mount->m_data; mutex_lock(&fmp->lock); /* Allocate free cluster for directory data */ error = fat_alloc_cluster(fmp, 0, &cl); if (error) goto out; memset(&np, 0, sizeof(struct fatfs_node)); de = &np.dirent; fat_convert_name(name, (char *)&de->name); de->cluster_hi = (cl & 0xFFFF0000) >> 16; de->cluster = cl & 0x0000FFFF; de->time = TEMP_TIME; de->date = TEMP_DATE; fat_mode_to_attr(mode, &de->attr); error = fatfs_add_node(dvp, &np); if (error) goto out; /* Initialize "." and ".." for new directory */ memset(fmp->io_buf, 0, fmp->cluster_size); de = (struct fat_dirent *)fmp->io_buf; memcpy(de->name, ". ", 11); de->attr = FA_SUBDIR; de->cluster_hi = (cl & 0xFFFF0000) >> 16; de->cluster = cl & 0x0000FFFF; de->time = TEMP_TIME; de->date = TEMP_DATE; de++; memcpy(de->name, ".. ", 11); de->attr = FA_SUBDIR; de->cluster_hi = (dvp->v_blkno & 0xFFFF0000) >> 16; de->cluster = dvp->v_blkno & 0x0000FFFF; de->time = TEMP_TIME; de->date = TEMP_DATE; if (fat_write_cluster(fmp, cl)) { error = EIO; goto out; } /* Add eof */ error = fat_set_cluster(fmp, cl, fmp->fat_eof); out: mutex_unlock(&fmp->lock); return error; }
static int fatfs_rename(vnode_t dvp1, vnode_t vp1, char *name1, vnode_t dvp2, vnode_t vp2, char *name2) { struct fatfsmount *fmp; struct fatfs_node np1; struct fat_dirent *de1, *de2; int error; fmp = dvp1->v_mount->m_data; mutex_lock(&fmp->lock); error = fatfs_lookup_node(dvp1, name1, &np1); if (error) goto out; de1 = &np1.dirent; if (IS_FILE(de1)) { /* Remove destination file, first */ error = fatfs_remove(dvp2, vp1, name2); if (error == EIO) goto out; /* Change file name of directory entry */ fat_convert_name(name2, (char *)de1->name); /* Same directory ? */ if (dvp1 == dvp2) { /* Change the name of existing file */ error = fatfs_put_node(fmp, &np1); if (error) goto out; } else { /* Create new directory entry */ error = fatfs_add_node(dvp2, &np1); if (error) goto out; /* Remove souce file */ error = fatfs_remove(dvp1, vp2, name1); if (error) goto out; } } else { /* remove destination directory */ error = fatfs_rmdir(dvp2, NULL, name2); if (error == EIO) goto out; /* Change file name of directory entry */ fat_convert_name(name2, (char *)de1->name); /* Same directory ? */ if (dvp1 == dvp2) { /* Change the name of existing directory */ error = fatfs_put_node(fmp, &np1); if (error) goto out; } else { /* Create new directory entry */ error = fatfs_add_node(dvp2, &np1); if (error) goto out; /* Update "." and ".." for renamed directory */ if (fat_read_cluster(fmp,(de1->cluster_hi << 16) | de1->cluster)) { error = EIO; goto out; } de2 = (struct fat_dirent *)fmp->io_buf; de2->cluster_hi = de1->cluster_hi; de2->cluster = de1->cluster; de2->time = TEMP_TIME; de2->date = TEMP_DATE; de2++; de2->cluster_hi = (dvp2->v_blkno & 0xFFFF0000) >> 16; de2->cluster = dvp2->v_blkno & 0x0000FFFF; de2->time = TEMP_TIME; de2->date = TEMP_DATE; if (fat_write_cluster(fmp,(de1->cluster_hi << 16) | de1->cluster)) { error = EIO; goto out; } /* Remove souce directory */ error = fatfs_rmdir(dvp1, NULL, name1); if (error) goto out; } } out: mutex_unlock(&fmp->lock); return error; }
static int fatfs_write(vnode_t vp, file_t fp, void *buf, size_t size, size_t *result) { struct fatfsmount *fmp; struct fatfs_node *np; struct fat_dirent *de; int nr_copy, nr_write, buf_pos, i, cl_size, error; u_long file_pos, end_pos; u_long cl; DPRINTF(("fatfs_write: vp=%x size=%d\n", vp, size)); *result = 0; fmp = vp->v_mount->m_data; if (vp->v_type == VDIR) return EISDIR; if (vp->v_type != VREG) return EINVAL; mutex_lock(&fmp->lock); /* Check if file position exceeds the end of file. */ end_pos = vp->v_size; file_pos = (fp->f_flags & O_APPEND) ? end_pos : fp->f_offset; if (file_pos + size > end_pos) { /* Expand the file size before writing to it */ end_pos = file_pos + size; error = fat_expand_file(fmp, vp->v_blkno, end_pos); if (error) { error = EIO; goto out; } /* Update directory entry */ np = vp->v_data; de = &np->dirent; de->size = end_pos; error = fatfs_put_node(fmp, np); if (error) goto out; vp->v_size = end_pos; } /* Seek to the cluster for the file offset */ error = fat_seek_cluster(fmp, vp->v_blkno, file_pos, &cl); if (error) goto out; buf_pos = file_pos % fmp->cluster_size; cl_size = size / fmp->cluster_size + 1; nr_write = 0; i = 0; do { /* First and last cluster must be read before write */ if (i == 0 || i == cl_size) { if (fat_read_cluster(fmp, cl)) { error = EIO; goto out; } } nr_copy = fmp->cluster_size; if (buf_pos > 0) nr_copy -= buf_pos; if (buf_pos + size < fmp->cluster_size) nr_copy = size; memcpy(fmp->io_buf + buf_pos, buf, nr_copy); if (fat_write_cluster(fmp, cl)) { error = EIO; goto out; } file_pos += nr_copy; nr_write += nr_copy; size -= nr_copy; if (size <= 0) break; error = fat_next_cluster(fmp, cl, &cl); if (error) goto out; buf = (void *)((u_long)buf + nr_copy); buf_pos = 0; i++; } while (!IS_EOFCL(fmp, cl)); fp->f_offset = file_pos; /* * XXX: Todo! * de.time = ? * de.date = ? * if (dirent_set(fp, &de)) * return EIO; */ *result = nr_write; error = 0; out: mutex_unlock(&fmp->lock); return error; }