Example #1
0
File: dir.c Project: bmiro/EmoFS
/** Des de l'inode del directori i el camí parcial obté l'inode del directori
 * i de l'entrada. Recorda que a la primera crida recursiva sempre li haurem
 * d'indicar p_inode_dir l'inode del directori arrel.
 * Convé usar extract_path per obtenir els subcamins.
 * @path: ruta, parcial o completa, del fitxer que buscam.
 * @p_inode_dir: l'inode del directori.
 * @p_inode: l'inode del fitxer.
 * @p_entry: entrada del fitxer dins el directori.
 * @return: 0 si èxit.
*/
int emofs_find_entry(const char *path, int *p_inode_dir,
		     int *p_inode, int *p_entry) {

	int found;
	int is_dir;
	char target [MAX_FILENAME_LEN];
	char tail [MAX_PATH_LEN];
	emofs_inode inode;
	emofs_dir_entry *dir_entry;
	int dir_entry_count;
	int i;
	emofs_superblock sb;

	/* Cas trivial del directori root */
	if(!strcmp(path, "/")) {
		sbread(&sb);
		*p_inode_dir = sb.root_inode;
		*p_inode = sb.root_inode;
		*p_entry = 0;
		return 0;
	}
	
	emofs_extract_path(path, target, tail);

	read_inode(*p_inode_dir, &inode);
	/* Cal recordar que no tenim desada enlloc la quantitat d'entrades que
	 * tenim dins el directori. Amb la divisió tamany_escrit/tamany_dades
	 * obtindrem quants d'elements tenim. */
	dir_entry_count = inode.size / sizeof(emofs_dir_entry);
	/* p_inode_dir -> inode del pare
	 * dir_entry -> l'entrada de directori: nom+inode
	 * dir_entry_count -> nombre de l'entrada dins el directori pare
	 */
	found = 0;
	for (i = 0; i < dir_entry_count; i++) {
		read_file(*p_inode_dir, (void *)&dir_entry, i*sizeof(emofs_dir_entry), \
			  sizeof(emofs_dir_entry));
		found = !strcmp(target, dir_entry->name);
		if (found) {
			break;
		}
	}
	if (!found) {
		return -1;
	}

	*p_entry = i; 
	*p_inode = dir_entry->inode;
	/* Si encara queda camí seguim amb les crides recursives */
	if (strcmp(tail, "")) {
		*p_inode_dir = dir_entry->inode;
		free(dir_entry);
		return emofs_find_entry(tail, p_inode_dir, p_inode, p_entry);
	}

	free(dir_entry);
	
	/* Si arribam aqui s'aturen les crides recursives. */
	return 0;
}
Example #2
0
File: dir.c Project: bmiro/EmoFS
/** Posa el contingut del directori en un buffer de memòria.
 * el nom de cada entrava ve separat per ':'.
 * Es ell qui reserva la memoria de buf i l'ha d'alliberar
 * la funcio que l'empri en haver acabat.
 * @path: Cami al directori
 * @buf: llistat de les entrades de directori separades per ':'
 * @return: numero de d'entrades llistades, -1 error, -2 era un fitxer.
*/
int emofs_dir(const char *path, char **buf) {
	int p_inode;
	emofs_inode inode;
	emofs_superblock sb;
	int p_entry; /* No s'empra pero es necessari per cridar find_entry */
	int p_inode_dir;
	int dir_entry_count;
	emofs_dir_entry *dir_entry;
	int error;
	int i, j, k;
	int used_entry_count = 0;
	int buffer_size = 0;

	sbread(&sb);
	p_inode_dir = sb.root_inode;
	error = emofs_find_entry(path, &p_inode_dir, &p_inode, &p_entry);

	if (error < 0) {
		return error;
	}
	
	read_inode(p_inode, &inode);
	dir_entry_count = inode.size/sizeof(emofs_dir_entry);

	*buf = malloc(sizeof(char));

	k = 0;
	for (i = 0; i < dir_entry_count; i++) {
		read_file(p_inode, (void *) &dir_entry, \
			i*sizeof(emofs_dir_entry), sizeof(emofs_dir_entry));
		if (dir_entry->inode != NULL_POINTER) {
			buffer_size += strlen(dir_entry->name)+1; /*Mes les ':'*/
			/*Memòria dinàmica, el que faltava per fer*/
			*buf = realloc(*buf, buffer_size*sizeof(char));
			if (*buf == NULL) {
				puts("Error redimensionant tamany de buffer.");
			}
			for(j = 0; dir_entry->name[j] != '\0'; j++) {
				(*buf)[k] = dir_entry->name[j];
				k++;
			}
			(*buf)[k] = ':'; /* separadors de nom de fitxer */
			k++;
			used_entry_count++;
		}
	}

	free(dir_entry);

	if (used_entry_count > 0) {
		/* Posam el final d'string substituint el separador */
		(*buf)[k-1] = '\0';
	} else {
		*buf = malloc(sizeof(char));
		(*buf)[k] = '\0'; /* k sera 0 */
	}

	return used_entry_count;
}
Example #3
0
File: dir.c Project: bmiro/EmoFS
/** Llegeix un cert nombre de bits d'un fitxer.
 * @path: Camí al destí
 * @buf: punter al buffer de sortida, la funcio s'encarrega de reservar l'espai.
 * @offset: determinam el primer byte del fitxer.
 * @n_bytes: nombre de bytes a llegir
 * @return: el nombre de bytes llegits.
*/
int emofs_read(const char *path, void **buf, int offset, int n_bytes) {
	int inode;
	emofs_superblock sb;
	int p_entry; /* No s'empra pero es necessari per cridar find_entry */
	int p_inode_dir;

	sbread(&sb);
	p_inode_dir = sb.root_inode;
	emofs_find_entry(path, &p_inode_dir, &inode, &p_entry);
	return read_file(inode, buf, offset, n_bytes);
}
Example #4
0
int
ufs_disk_fillout(struct uufsd *disk, const char *name)
{
	if (ufs_disk_fillout_blank(disk, name) == -1) {
		return (-1);
	}
	if (sbread(disk) == -1) {
		ERROR(disk, "could not read superblock to fill out disk");
		return (-1);
	}
	return (0);
}
Example #5
0
static SPWAW_ERROR
load_oobp_list (SBR *sbr, USHORT cnt, SPWAW_SNAP_OOB_RAW *oob, STRTAB *stab)
{
	ULONG		i;
	SNAP_OOB_PEL	p;

	for (i=0; i<cnt; i++) {
		if (sbread (sbr, (char *)&p, sizeof (p)) != sizeof (p))
			RWE (SPWERR_FRFAILED, "sbread(position data)");
		load_oobp (&p, &(oob->positions.raw[i]), stab);
	}

	return (SPWERR_OK);
}
Example #6
0
static SPWAW_ERROR
load_oobl_list (SBR *sbr, USHORT cnt, SPWAW_SNAP_OOB_RAW *oob, STRTAB *stab)
{
	ULONG		i;
	SNAP_OOB_LEL	l;

	for (i=0; i<cnt; i++) {
		if (sbread (sbr, (char *)&l, sizeof (l)) != sizeof (l))
			RWE (SPWERR_FRFAILED, "sbread(leader data)");
		load_oobl (&l, &(oob->leaders.raw[i]), stab);
	}

	return (SPWERR_OK);
}
Example #7
0
static SPWAW_ERROR
load_oobf_list (SBR *sbr, USHORT cnt, SPWAW_SNAP_OOB_RAW *oob, STRTAB *stab)
{
	ULONG		i;
	SNAP_OOB_FEL	f;

	for (i=0; i<cnt; i++) {
		if (sbread (sbr, (char *)&f, sizeof (f)) != sizeof (f))
			RWE (SPWERR_FRFAILED, "sbread(formation data)");
		load_oobf (&f, &(oob->formations.raw[i]), stab);
	}

	return (SPWERR_OK);
}
Example #8
0
File: dir.c Project: bmiro/EmoFS
/** Escriu un cert nombre de bits d'un fitxer. Té control de concurrència.
 * @path: Camí al destí
 * @buf: buffer de entrada.
 * @offset: determinam el primer byte del fitxer.
 * @n_bytes: nombre de bytes a escriure
 * @return: el nombre de bytes escriure.
*/
int emofs_write(const char *path, const void *buf, int offset, int n_bytes) {
	int inode, error;
	emofs_superblock sb;
        /* No s'empra pero es necessari per cridar find_entry */
	int p_entry; 
	int p_inode_dir;

	if(!mutex){
		emofs_sem_get(&mutex);
	}
	emofs_sem_wait(mutex);
	sbread(&sb);
	p_inode_dir = sb.root_inode;
	emofs_find_entry(path, &p_inode_dir, &inode, &p_entry);
	error = write_file(inode, buf, offset, n_bytes);
	emofs_sem_signal(mutex);
	return error;
}
Example #9
0
static SPWAW_ERROR
load_oobu_list (SBR *sbr, USHORT cnt, SPWAW_SNAP_OOB_RAW *oob, STRTAB *stab, ULONG version)
{
	ULONG		i;
	SNAP_OOB_UEL	u;

	for (i=0; i<cnt; i++) {
		/* We are now backwards compatible with version 10 */
		if (version == SNAP_VERSION_V10) {
			snapshot_load_v10_oob_uel (sbr, &u);
		} else {
			if (sbread (sbr, (char *)&u, sizeof (u)) != sizeof (u))
				RWE (SPWERR_FRFAILED, "sbread(unit data)");
		}
		load_oobu (&u, &(oob->units.raw[i]), stab);
	}

	return (SPWERR_OK);
}
Example #10
0
File: dir.c Project: bmiro/EmoFS
/** Obté la informació d'un fitxer o directori 
 * @path: Cami al fitxer/directori.
 * @stat: el punter de sortida de les dades.
 * @return: 0 si èxit.
*/
int emofs_stat(const char *path, emofs_inode_stat *stat) {
	int inode = 0;
	emofs_superblock sb;
	int p_entry = 0; /* No s'empra pero es necessari per cridar find_entry */
	int p_inode_dir = 0;
	int error = 0;

	sbread(&sb);
	p_inode_dir = sb.root_inode;
	error = emofs_find_entry(path, &p_inode_dir, &inode, &p_entry);
	if(error < 0) {
		puts("emofs_stat: no s'ha trobat entrada");
		return error;
	}
	if(inode < 0) {
		puts("emofs_stat: inode negatiu");
		return -1;
	}
	error = stat_file(inode, stat);
	return error;
}
Example #11
0
/*
 * Read information about /boot's inode, then put this and filesystem
 * parameters from the superblock into pbr_symbols.
 */
static int
getbootparams(char *boot, int devfd, struct disklabel *dl)
{
	int		fd;
	struct stat	statbuf, sb;
	struct statfs	statfsbuf;
	struct partition *pp;
	struct fs	*fs;
	char		*buf;
	u_int		blk, *ap;
	struct ufs1_dinode	*ip1;
	struct ufs2_dinode	*ip2;
	int		ndb;
	int		mib[3];
	size_t		size;
	dev_t		dev;
	int		skew;

	/*
	 * Open 2nd-level boot program and record enough details about
	 * where it is on the filesystem represented by `devfd'
	 * (inode block, offset within that block, and various filesystem
	 * parameters essentially taken from the superblock) for biosboot
	 * to be able to load it later.
	 */

	/* Make sure the (probably new) boot file is on disk. */
	sync(); sleep(1);

	if ((fd = open(boot, O_RDONLY)) < 0)
		err(1, "open: %s", boot);

	if (fstatfs(fd, &statfsbuf) != 0)
		err(1, "statfs: %s", boot);

	if (strncmp(statfsbuf.f_fstypename, "ffs", MFSNAMELEN) &&
	    strncmp(statfsbuf.f_fstypename, "ufs", MFSNAMELEN) )
		errx(1, "%s: not on an FFS filesystem", boot);

#if 0
	if (read(fd, &eh, sizeof(eh)) != sizeof(eh))
		errx(1, "read: %s", boot);

	if (!IS_ELF(eh)) {
		errx(1, "%s: bad magic: 0x%02x%02x%02x%02x",
		    boot,
		    eh.e_ident[EI_MAG0], eh.e_ident[EI_MAG1],
		    eh.e_ident[EI_MAG2], eh.e_ident[EI_MAG3]);
	}
#endif

	if (fsync(fd) != 0)
		err(1, "fsync: %s", boot);

	if (fstat(fd, &statbuf) != 0)
		err(1, "fstat: %s", boot);

	if (fstat(devfd, &sb) != 0)
		err(1, "fstat: %s", realdev);

	/* Check devices. */
	mib[0] = CTL_MACHDEP;
	mib[1] = CPU_CHR2BLK;
	mib[2] = sb.st_rdev;
	size = sizeof(dev);
	if (sysctl(mib, 3, &dev, &size, NULL, 0) >= 0) {
		if (statbuf.st_dev / MAXPARTITIONS != dev / MAXPARTITIONS)
			errx(1, "cross-device install");
	}

	pp = &dl->d_partitions[DISKPART(statbuf.st_dev)];
	close(fd);

	sbread(devfd, DL_SECTOBLK(dl, DL_GETPOFFSET(pp)), &fs);

	/* Read inode. */
	if ((buf = malloc(fs->fs_bsize)) == NULL)
		err(1, NULL);

	blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino));

	/*
	 * Have the inode.  Figure out how many filesystem blocks (not disk
	 * sectors) there are for biosboot to load.
	 */
	devread(devfd, buf, DL_SECTOBLK(dl, pp->p_offset) + blk,
	    fs->fs_bsize, "inode");
	if (fs->fs_magic == FS_UFS2_MAGIC) {
		ip2 = (struct ufs2_dinode *)(buf) +
		    ino_to_fsbo(fs, statbuf.st_ino);
		ndb = howmany(ip2->di_size, fs->fs_bsize);
		ap = (u_int *)ip2->di_db;
		skew = sizeof(u_int32_t);
	} else {
		ip1 = (struct ufs1_dinode *)(buf) +
		    ino_to_fsbo(fs, statbuf.st_ino);
		ndb = howmany(ip1->di_size, fs->fs_bsize);
		ap = (u_int *)ip1->di_db;
		skew = 0;
	}
	if (ndb <= 0)
		errx(1, "No blocks to load");

	/*
	 * Now set the values that will need to go into biosboot
	 * (the partition boot record, a.k.a. the PBR).
	 */
	sym_set_value(pbr_symbols, "_fs_bsize_p", (fs->fs_bsize / 16));
	sym_set_value(pbr_symbols, "_fs_bsize_s", (fs->fs_bsize / 
	    dl->d_secsize));

	/*
	 * fs_fsbtodb is the shift to convert fs_fsize to DEV_BSIZE. The
	 * ino_to_fsba() return value is the number of fs_fsize units.
	 * Calculate the shift to convert fs_fsize into physical sectors,
	 * which are added to p_offset to get the sector address BIOS
	 * will use.
	 *
	 * N.B.: ASSUMES fs_fsize is a power of 2 of d_secsize.
	 */
	sym_set_value(pbr_symbols, "_fsbtodb",
	    ffs(fs->fs_fsize / dl->d_secsize) - 1);

	if (pp->p_offseth != 0)
		errx(1, "partition offset too high");
	sym_set_value(pbr_symbols, "_p_offset", pp->p_offset);
	sym_set_value(pbr_symbols, "_inodeblk",
	    ino_to_fsba(fs, statbuf.st_ino));
	sym_set_value(pbr_symbols, "_inodedbl",
	    ((((char *)ap) - buf) + INODEOFF));
	sym_set_value(pbr_symbols, "_nblocks", ndb);
	sym_set_value(pbr_symbols, "_blkskew", skew);

	if (verbose) {
		fprintf(stderr, "%s is %d blocks x %d bytes\n",
		    boot, ndb, fs->fs_bsize);
		fprintf(stderr, "fs block shift %u; part offset %llu; "
		    "inode block %lld, offset %u\n",
		    ffs(fs->fs_fsize / dl->d_secsize) - 1,
		    DL_GETPOFFSET(pp), ino_to_fsba(fs, statbuf.st_ino),
		    (unsigned int)((((char *)ap) - buf) + INODEOFF));
		fprintf(stderr, "expecting %d-bit fs blocks (skew %d)\n",
		    skew ? 64 : 32, skew);
	}

	return 0;
}
Example #12
0
/*
 * Creacio del fitxer on es te el sistema de fitxers.
 * mi_mkfs <cantidad_bloques>
 * codis de retorn:
 * 	0: correcte
 * 	-1: nombre de parametres incorrecte
 */
int main(int argc, char **argv) {
	int i = 0;
	int nombre_blocs;
	int n_inode;
	emofs_superblock sb;
	emofs_inode inode;
	/* Some fun */
	char author[][20] = { AUTHOR_B, AUTHOR_P };
	char buf[80];
	char path[MAX_PATH_LEN];
	int ascii_art; /* ASCII art, descriptor de fitxer */
	int pos;
	int read_bytes;

	emofs_block bloc_zero = block_of_zero();

	if (argc != 2) {
		nombre_blocs = DEFAULT_BLOCKS;
	} else {
		nombre_blocs = atoi(argv[1]);
	}

	bmount();

	/* Inicialitzam tot el sistema de fitxers */
	for (i = 0; i < nombre_blocs; i++) {
		bwrite(i, &bloc_zero);
	}
 
	init_superblock(nombre_blocs);
	init_bitmap();
	init_inode_array();

	/* Problema de bootstrap. Es necessita una ruta per crear un fitxer. */
	n_inode = alloc_inode(DIRECTORY_INODE);
	sbread(&sb);
	sb.root_inode = n_inode;
	sbwrite(&sb);

	/* JUST FOR FUN */
	/* Cream directori /authors */
	if (fork() == 0) {
		execl("mi_mkdir", "mi_mkdir", "/authors", (char *)0);
	} else {
		wait3(NULL, 0, NULL);
	}
	/* Cream i omplim /authors/author[i].ascii" */
	for (i = 0; i < AUTHOR_COUNT; i++) {	
		ascii_art = open(author[i], O_RDONLY, S_IRUSR);
		strcpy(path, "/authors/");	
		strcat(path, author[i]);
		emofs_create(path);
		pos = 0;
		read_bytes = 1; /* per entrar al bucle */
		while (read_bytes > 0) { /* Sortira amb el break */
			lseek(ascii_art, pos, SEEK_SET);
			read_bytes = read(ascii_art, buf, 80);
			if (!read_bytes) break;
			emofs_write(path, buf, pos, read_bytes);
			pos += read_bytes;
		}


		close(ascii_art);
	}
	/* ending fun */

    	bumount();

	return 0;
}
Example #13
0
File: dir.c Project: bmiro/EmoFS
/** Crea un fitxer o directori i la seva entrada de directori. 
* Princpipalment empra les funcoons find_entry, alloc_inode, write_file
* @path: ruta del fitxer a crear
* @return: 0 si es crea correctament.
*	   -1 en cas d'error.
*/
int emofs_create(const char *path) {
	emofs_superblock sb;
	int i = 0;
	int p_inode_dir;
	int p_inode;
	int p_new_inode;
	int p_entry;
	emofs_inode inode;
	int type;
	char partial_path[MAX_PATH_LEN];
	char new_dir_file[MAX_FILENAME_LEN];
	int error = 0;
	int dir_entry_count;
	emofs_dir_entry dir_entry;
	
	if(!mutex){
		emofs_sem_get(&mutex);
	}
	emofs_sem_wait(mutex);

	sbread(&sb);
	if (emofs_file_exists(path)) {
		/* Existeix, per tant no el podem crear */
		puts("emofs_create: El fitxer o directori ja existeix");
		emofs_sem_signal(mutex);
		return -1;
	}
	
	type = emofs_get_partial_path(path, partial_path, new_dir_file);
	
	/* Comprovam que existeixi la ruta on crear el fitxer o directori */
	p_inode_dir = sb.root_inode;
	if (emofs_find_entry(partial_path, \
			     &p_inode_dir, &p_inode, &p_entry) == -1) {
		puts("emofs_create: El directori on es preten fer " \
		     "la creació no existeix");
		printf("partial_path %s\n", partial_path);
		printf("p_inode_dir: %d, p_inode: %d, p_entry: %d\n", \
		       p_inode_dir, p_inode, p_entry);
		emofs_sem_signal(mutex);
		return error;
	}

	/* Obtenim el directori on volem crear l'entrada */
	p_inode_dir = sb.root_inode;
	emofs_find_entry(path, &p_inode_dir, &p_inode, &p_entry);

	dir_entry.inode = alloc_inode(type); /* Aqui reservam l'inode */
	if (dir_entry.inode == -1) {
		emofs_sem_signal(mutex);
		return -1;
	}
	for(i = 0; i < MAX_FILENAME_LEN; i++) {
		dir_entry.name[i] = ' ';
	}
	strcpy(dir_entry.name, new_dir_file);

	/* Llegim inode del directori del pare per saber el seu tamany i poder
	 * escriure al final. */
	read_inode(p_inode_dir, &inode);
	error = write_file(p_inode_dir, &dir_entry, inode.size, \
			   sizeof(emofs_dir_entry));
	if ( error < 0) {
		puts("emofs_create: Error d'escriptura");
		emofs_sem_signal(mutex);
		return error;
	}
	emofs_sem_signal(mutex);
	return error;
}