Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}