Пример #1
0
/*
 * Find directory entry for specified name in directory.
 * The fat vnode data is filled if success.
 *
 * @dvp: vnode for directory.
 * @name: file name
 * @np: pointer to fat node
 */
int
fatfs_lookup_node(vnode_t dvp, char *name, struct fatfs_node *np)
{
	struct fatfsmount *fmp;
	char fat_name[12];
	u_long i, cl, sec, sec_start;
	int err;

	if (name == NULL)
		return ENOENT;

	DPRINTF(("fat_lookup_denode: cl=%d name=%s\n", dvp->v_blkno, name));

	fat_convert_name(name, fat_name);
	*(fat_name + 11) = '\0';

	fmp = (struct fatfsmount *)dvp->v_mount->m_data;
	cl = dvp->v_blkno;
	if (cl == CL_ROOT && !(FAT32(fmp))) {
		/* Search entry in root directory */
		sec_start = fmp->root_start;
		for (sec = sec_start; sec < fmp->data_start; sec++) {
			err = fat_lookup_dirent(fmp, sec, fat_name, np);
			if (err != EAGAIN)
				return err;
		}
	} else {
		/* Search entry in sub directory */
		if(cl == CL_ROOT)	/* CL_ROOT of FAT32 */
			cl = fmp->root_start;
		while (!IS_EOFCL(fmp, cl)) {
			sec = cl_to_sec(fmp, cl);
			for (i = 0; i < fmp->sec_per_cl; i++) {
				err = fat_lookup_dirent(fmp, sec, fat_name,
						   np);
				if (err != EAGAIN)
					return err;
				sec++;
			}
			err = fat_next_cluster(fmp, cl, &cl);
			if (err)
				return err;
		}
	}
	return ENOENT;
}
Пример #2
0
/*
 * Create empty file.
 */
static int
fatfs_create(vnode_t dvp, char *name, mode_t mode)
{
    struct fatfsmount *fmp;
    struct fatfs_node np;
    struct fat_dirent *de;
    u_long cl;
    int error;

    DPRINTF(("fatfs_create: %s\n", name));

    if (!S_ISREG(mode))
        return EINVAL;

    if (!fat_valid_name(name))
        return EINVAL;

    fmp = dvp->v_mount->m_data;
    mutex_lock(&fmp->lock);

    /* Allocate free cluster for new file. */
    error = fat_alloc_cluster(fmp, 0, &cl);
    if (error)
        goto out;

    de = &np.dirent;
    memset(de, 0, sizeof(struct fat_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;
    error = fat_set_cluster(fmp, cl, fmp->fat_eof);
out:
    mutex_unlock(&fmp->lock);
    return error;
}
Пример #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;
}