Ejemplo n.º 1
0
static int _validate_cs_(nspace *vol, uint32 cluster, uint32 sector)
{
    if (sector < 0) return -1;

    if ((vol->fat_bits != 32) && IS_FIXED_ROOT(cluster)) { // fat12 or fat16 root
        if (sector >= vol->root_sectors)
            return -1;
        return 0;
    }

    if (sector >= vol->sectors_per_cluster) return -1;

    if (!IS_DATA_CLUSTER(cluster)) return -1;

    return 0;
}
Ejemplo n.º 2
0
static status_t
get_next_dirent(nspace *vol, vnode *dir, struct diri *iter, ino_t *vnid,
	char *filename, int len)
{
	struct _dirent_info_ info;
	status_t result;

	do {
		result = _next_dirent_(iter, &info, filename, len);
		if (result < 0)
			return result;
		// only hide volume label entries in the root directory
	} while ((info.mode & FAT_VOLUME) && (dir->vnid == vol->root_vnode.vnid));

	if (!strcmp(filename, ".")) {
		// assign vnode based on parent
		if (vnid) *vnid = dir->vnid;
	} else if (!strcmp(filename, "..")) {
		// assign vnode based on parent of parent
		if (vnid) *vnid = dir->dir_vnid;
	} else {
		if (vnid) {
			ino_t loc = (IS_DATA_CLUSTER(info.cluster))
				? GENERATE_DIR_CLUSTER_VNID(dir->vnid, info.cluster)
				: GENERATE_DIR_INDEX_VNID(dir->vnid, info.sindex);
			bool added_to_vcache = false;

			/* if it matches a loc in the lookup table, we are done. */
			result = vcache_loc_to_vnid(vol, loc, vnid);
			if (result == ENOENT) {
				/* ...else check if it matches any vnid's in the lookup table */
				if (find_vnid_in_vcache(vol, loc) == B_OK) {
					/* if it does, create a random one since we can't reuse
					 * existing vnid's */
					*vnid = generate_unique_vnid(vol);
					/* and add it to the vcache */
					if ((result = add_to_vcache(vol, *vnid, loc)) < 0)
						return result;
					added_to_vcache = true;
				} else {
					/* otherwise we are free to use it */
					*vnid = loc;
				}
			} else if (result != B_OK) {
				dprintf("get_next_dirent: unknown error (%s)\n",
					strerror(result));
				return result;
			}

			if (info.mode & FAT_SUBDIR) {
				if (dlist_find(vol, info.cluster) == -1LL) {
					if ((result = dlist_add(vol, *vnid)) < 0) {
						if (added_to_vcache)
							remove_from_vcache(vol, *vnid);
						return result;
					}
				}
			}
		}
	}

	DPRINTF(2, ("get_next_dirent: found %s (vnid %Lx)\n", filename,
		vnid != NULL ? *vnid : (ino_t)0));

	return B_NO_ERROR;
}