Esempio n. 1
0
/*
 * Find empty directory entry and put new entry on it.
 * This search is done only in directory of specified cluster.
 * @dvp: vnode for directory.
 * @np: pointer to fat node
 */
int
fatfs_add_node(vnode_t dvp, struct fatfs_node *np)
{
	struct fatfsmount *fmp;
	u_long cl, sec, sec_start;
	int err;
	u_long i, next;

	fmp = (struct fatfsmount *)dvp->v_mount->m_data;
	cl = dvp->v_blkno;

	DPRINTF(("fatfs_add_node: cl=%d\n", cl));

	if (cl == CL_ROOT && !(FAT32(fmp))) {
		/* Add entry in root directory */
		sec_start = fmp->root_start;
		for (sec = sec_start; sec < fmp->data_start; sec++) {
			err = fat_add_dirent(fmp, sec, np);
			if (err != ENOENT)
				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_add_dirent(fmp, sec, np);
				if (err != ENOENT)
					return err;
				sec++;
			}
			err = fat_next_cluster(fmp, cl, &next);
			if (err)
				return err;
			cl = next;
		}
		/* No entry found, add one more free cluster for directory */
		DPRINTF(("fatfs_add_node: expand dir\n"));
		err = fat_expand_dir(fmp, cl, &next);
		if (err)
			return err;

		/* Initialize free cluster. */
		memset(fmp->dir_buf, 0, SEC_SIZE);
		sec = cl_to_sec(fmp, next);
		for (i = 0; i < fmp->sec_per_cl; i++) {
			err = fat_write_dirent(fmp, sec);
			if (err)
				return err;
			sec++;
		}
		/* Try again */
		sec = cl_to_sec(fmp, next);
		err = fat_add_dirent(fmp, sec, np);
		return err;
	}
	return ENOENT;
}
Esempio n. 2
0
/*
 * Read one cluster to buffer.
 */
static int
fat_read_cluster(struct fatfsmount *fmp, u_long cluster)
{
    u_long sec;
    size_t size;

    sec = cl_to_sec(fmp, cluster);
    size = fmp->sec_per_cl * SEC_SIZE;
    return device_read(fmp->dev, fmp->io_buf, &size, sec);
}
Esempio n. 3
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;
}
Esempio n. 4
0
/*
 * Get directory entry for specified index.
 *
 * @dvp: vnode for directory.
 * @index: index of the entry
 * @np: pointer to fat node
 */
int
fatfs_get_node(vnode_t dvp, int index, struct fatfs_node *np)
{
	struct fatfsmount *fmp;
	u_long i, cl, sec, sec_start;
	int cur_index, err;

	fmp = (struct fatfsmount *)dvp->v_mount->m_data;
	cl = dvp->v_blkno;
	cur_index = 0;

	DPRINTF(("fatfs_get_node: index=%d\n", index));

	if (cl == CL_ROOT && !(FAT32(fmp))) {
		/* Get entry from the root directory */
		sec_start = fmp->root_start;
		for (sec = sec_start; sec < fmp->data_start; sec++) {
			err = fat_get_dirent(fmp, sec, index, &cur_index, np);
			if (err != EAGAIN)
				return err;
		}
	} else {
		if(cl == CL_ROOT)	/* CL_ROOT of FAT32 */
			cl = fmp->root_start;
		/* Get entry from the sub directory */
		while (!IS_EOFCL(fmp, cl)) {
			sec = cl_to_sec(fmp, cl);
			for (i = 0; i < fmp->sec_per_cl; i++) {
				err = fat_get_dirent(fmp, sec, index,
						     &cur_index, np);
				if (err != EAGAIN)
					return err;
				sec++;
			}
			err = fat_next_cluster(fmp, cl, &cl);
			if (err)
				return err;
		}
	}
	return ENOENT;
}