Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
int fat_directory_write(fat_directory_t *di, const char *name, fat_dentry_t *de)
{
	int rc;
	void *data;
	fat_instance_t *instance;

	rc = fs_instance_get(di->nodep->idx->service_id, &data);
	assert(rc == EOK);
	instance = (fat_instance_t *) data;
	
	if (fat_valid_short_name(name)) {
		/*
		 * NAME could be directly stored in dentry without creating
		 * LFN.
		 */
		fat_dentry_name_set(de, name);
		if (fat_directory_is_sfn_exist(di, de))
			return EEXIST;
		rc = fat_directory_lookup_free(di, 1);
		if (rc != EOK)
			return rc;
		rc = fat_directory_write_dentry(di, de);
		return rc;
	} else if (instance->lfn_enabled && fat_valid_name(name)) {
		/* We should create long entries to store name */
		int long_entry_count;
		uint8_t checksum;
		uint16_t wname[FAT_LFN_NAME_SIZE];
		size_t lfn_size, lfn_offset;
		
		rc = str_to_utf16(wname, FAT_LFN_NAME_SIZE, name);
		if (rc != EOK)
			return rc;
		
		lfn_size = utf16_length(wname);
		long_entry_count = lfn_size / FAT_LFN_ENTRY_SIZE;
		if (lfn_size % FAT_LFN_ENTRY_SIZE)
			long_entry_count++;
		rc = fat_directory_lookup_free(di, long_entry_count + 1);
		if (rc != EOK)
			return rc;
		aoff64_t start_pos = di->pos;

		/* Write Short entry */
		rc = fat_directory_create_sfn(di, de, name);
		if (rc != EOK)
			return rc;
		checksum = fat_dentry_chksum(de->name);

		rc = fat_directory_seek(di, start_pos + long_entry_count);
		if (rc != EOK)
			return rc;
		rc = fat_directory_write_dentry(di, de);
		if (rc != EOK)
			return rc;

		/* Write Long entry by parts */
		lfn_offset = 0;
		fat_dentry_t *d;
		size_t idx = 0;
		do {
			rc = fat_directory_prev(di);
			if (rc != EOK)
				return rc;
			rc = fat_directory_get(di, &d);
			if (rc != EOK)
				return rc;
			fat_lfn_set_entry(wname, &lfn_offset, lfn_size + 1, d);
			FAT_LFN_CHKSUM(d) = checksum;
			FAT_LFN_ORDER(d) = ++idx;
			di->b->dirty = true;
		} while (lfn_offset < lfn_size);
		FAT_LFN_ORDER(d) |= FAT_LFN_LAST;

		rc = fat_directory_seek(di, start_pos + long_entry_count);
		return rc;
	}

	return ENOTSUP;
}
Ejemplo n.º 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;
}