Ejemplo n.º 1
0
static int testfs_checkfs(struct super_block *sb, struct bitmap *i_freemap,
		struct bitmap *b_freemap, int inode_nr) {
	struct inode *in = testfs_get_inode(sb, inode_nr);
	int size;
	int size_roundup = ROUNDUP(testfs_inode_get_size(in), BLOCK_SIZE);

	assert((testfs_inode_get_type(in) == I_FILE) || (testfs_inode_get_type(in) == I_DIR));

	/* inode processing */
	bitmap_mark(i_freemap, inode_nr);
	if (testfs_inode_get_type(in) == I_DIR) {
		int offset = 0;
		struct dirent *d;
		for (; (d = testfs_next_dirent(in, &offset)); free(d)) {
			if ((d->d_inode_nr < 0) || (strcmp(D_NAME(d), ".") == 0)
					|| (strcmp(D_NAME(d), "..") == 0))
				continue;
			testfs_checkfs(sb, i_freemap, b_freemap, d->d_inode_nr);
		}
	}
	/* block processing */
	size = testfs_check_inode(sb, b_freemap, in);
	assert(size == size_roundup);
	testfs_put_inode(in);
	return 0;
}
Ejemplo n.º 2
0
static int
testfs_pwd(struct super_block *sb, struct inode *in)
{
        int p_inode_nr;
        struct inode *p_in;
        struct dirent *d;
        int ret;

        assert(in);
        assert(testfs_inode_get_nr(in) >= 0);
        p_inode_nr = testfs_dir_name_to_inode_nr(in, "..");
        assert(p_inode_nr >= 0);
        if (p_inode_nr == testfs_inode_get_nr(in)) {
                printf("/");
                return 1;
        }
        p_in = testfs_get_inode(sb, p_inode_nr);
        d = testfs_find_dirent(p_in, testfs_inode_get_nr(in));
        assert(d);
        ret = testfs_pwd(sb, p_in);
        testfs_put_inode(p_in);
        printf("%s%s", ret == 1 ? "" : "/", D_NAME(d));
        free(d);
        return 0;
}
Ejemplo n.º 3
0
int
cmd_write(struct super_block *sb, struct context *c)
{
        int inode_nr;
        struct inode *in;
        int size;
        int ret = 0;
        char * filename = c->cmd[1];
        char * content = c->cmd[2];

        if (c->nargs != 3) {
                return -EINVAL;
        }
        inode_nr = testfs_dir_name_to_inode_nr(c->cur_dir, filename);
        if (inode_nr < 0)
                return inode_nr;
        in = testfs_get_inode(sb, inode_nr);
        if (testfs_inode_get_type(in) == I_DIR) {
                ret = -EISDIR;
                goto out;
        }
        size = strlen(content);
        testfs_tx_start(sb, TX_WRITE);
        ret = testfs_write_data(in, 0, content, size);
        if (ret >= 0) {
                testfs_truncate_data(in, size);
        }
        testfs_sync_inode(in);
        testfs_tx_commit(sb, TX_WRITE);
out:
        testfs_put_inode(in);
        return ret;
}
Ejemplo n.º 4
0
int
cmd_cd(struct super_block *sb, struct context *c)
{
        int inode_nr;
        struct inode *dir_inode;

        if (c->nargs != 2) {
                return -EINVAL;
        }
        inode_nr = testfs_dir_name_to_inode_nr(c->cur_dir, c->cmd[1]);
        if (inode_nr < 0)
                return inode_nr;
        dir_inode = testfs_get_inode(sb, inode_nr);
        if (testfs_inode_get_type(dir_inode) != I_DIR) {
                testfs_put_inode(dir_inode);
                return -ENOTDIR;
        }
        testfs_put_inode(c->cur_dir);
        c->cur_dir = dir_inode;
        return 0;
}
Ejemplo n.º 5
0
int main(int argc, char * const argv[]) {
	struct super_block *sb;
	char *line = NULL;
	size_t line_size = 0;
	ssize_t nr;
	int ret;
	struct context c;
	// context contains command line arguments/parameters,
	// inode of directory from which cmd was issued, and no of args.

	struct args * args = parse_arguments(argc, argv);

	// args->disk contains the name of the disk file. 
	// initializes the in memory structure sb with data that is 
	// read from the disk. after successful execution, we have 
	// sb initialized to dsuper_block read from disk.
	ret = testfs_init_super_block(args->disk, args->corrupt, &sb);
	//fslice_clear();	
	if (ret) {
		EXIT("testfs_init_super_block");
	}
	/* if the inode does not exist in the inode_hash_map (which
	 is an inmemory map of all inode blocks, create a new inode by
	 allocating memory to it. read the dinode from disk into that
	 memory inode
	 */
	c.cur_dir = testfs_get_inode(sb, 0); /* root dir */
	for (;
	PROMPT, (nr = getline(&line, &line_size, stdin)) != EOF;) {
		char * name;
		char * args;

		printf("command: %s\n", line);
		name = strtok(line, " \t\n");
		args = strtok(NULL, "\n");
		handle_command(sb, &c, name, args);

		if (can_quit) {
			break;
		}
	}

	free(line);
	// decrement inode count by 1. remove inode from in_memory hash map if
	// inode count has become 0.
	testfs_put_inode(c.cur_dir);
	testfs_close_super_block(sb);
	return 0;
}
Ejemplo n.º 6
0
static int
testfs_create_file_or_dir(struct super_block *sb, struct inode *dir,
                          inode_type type, char *name)
{
        int ret = 0;
        struct inode *in;
        int inode_nr;

        if (dir) {
                inode_nr = testfs_dir_name_to_inode_nr(dir, name);
                if (inode_nr >= 0)
                        return -EEXIST;
        }
        testfs_tx_start(sb, TX_CREATE);
        /* first create inode */
        ret = testfs_create_inode(sb, type, &in);
        if (ret < 0) {
                goto fail;
        }
        inode_nr = testfs_inode_get_nr(in);
        if (type == I_DIR) { /* create directory */
                int p_inode_nr = dir ? testfs_inode_get_nr(dir) : inode_nr;
                ret = testfs_create_empty_dir(sb, p_inode_nr, in);
                if (ret < 0)
                        goto out;
        }
        /* then add directory entry */
        if (dir) {
                if ((ret = testfs_add_dirent(dir, name, inode_nr)) < 0)
                        goto out;
                testfs_sync_inode(dir);
        }
        testfs_sync_inode(in);
        testfs_put_inode(in);
        testfs_tx_commit(sb, TX_CREATE);
        return 0;
out:
        testfs_remove_inode(in);
fail:
        testfs_tx_commit(sb, TX_CREATE);
        return ret;
}
Ejemplo n.º 7
0
int
cmd_cat(struct super_block *sb, struct context *c)
{
        char *buf;
        int inode_nr;
        struct inode *in;
        int ret = 0;
        int sz;
        int i;

        if (c->nargs < 2) {
                return -EINVAL;
        }    
        for (i = 1; ret == 0 && i < c->nargs; i++ )
        {
                inode_nr = testfs_dir_name_to_inode_nr(c->cur_dir, c->cmd[i]);
                if (inode_nr < 0)
                        return inode_nr;
                in = testfs_get_inode(sb, inode_nr);
                if (testfs_inode_get_type(in) == I_DIR) {
                        ret = -EISDIR;
                        goto out;
                }
                sz = testfs_inode_get_size(in);
                if (sz > 0) {
                        buf = malloc(sz + 1);
                        if (!buf) {
                                ret = -ENOMEM;
                                goto out;
                        }
                        testfs_read_data(in, 0, buf, sz);
                        buf[sz] = 0;
                        printf("%s\n", buf);
                        free(buf);
                }
out:
                testfs_put_inode(in);                
        }

        return ret;
}
Ejemplo n.º 8
0
/* returns negative value if name within dir is not empty */
static int
testfs_remove_dirent_allowed(struct super_block *sb, int inode_nr)
{
        struct inode *dir;
        int offset = 0;
        struct dirent *d;
        int ret = 0;

        dir = testfs_get_inode(sb, inode_nr);
        if (testfs_inode_get_type(dir) != I_DIR)
                goto out;
        for (; ret == 0 && (d = testfs_next_dirent(dir, &offset)); free(d)) {
                if ((d->d_inode_nr < 0) || (strcmp(D_NAME(d), ".") == 0) || 
                    (strcmp(D_NAME(d), "..") == 0))
                        continue;
                ret = -ENOTEMPTY;
        }
out:
        testfs_put_inode(dir);
        return ret;
}
Ejemplo n.º 9
0
int
cmd_lsr(struct super_block *sb, struct context *c)
{
        int inode_nr;
        struct inode *in;
        char *cdir = ".";

        if (c->nargs != 1 && c->nargs != 2) {
                return -EINVAL;
        }
        if (c->nargs == 2) {
                cdir = c->cmd[1];
        }
        assert(c->cur_dir);
        inode_nr = testfs_dir_name_to_inode_nr(c->cur_dir, cdir);
        if (inode_nr < 0)
                return inode_nr;
        in = testfs_get_inode(sb, inode_nr);
        testfs_ls(in, 1);
        testfs_put_inode(in);
        return 0;
}
Ejemplo n.º 10
0
int
cmd_stat(struct super_block *sb, struct context *c)
{
        int inode_nr;
        struct inode *in;
        int i;

        if (c->nargs < 2) {
                return -EINVAL;
        }   
        for (i = 1; i < c->nargs; i++ )
        {
                inode_nr = testfs_dir_name_to_inode_nr(c->cur_dir, c->cmd[i]);
                if (inode_nr < 0)
                        return inode_nr;
                in = testfs_get_inode(sb, inode_nr);
                printf("%s: i_nr = %d, i_type = %d, i_size = %d\n", c->cmd[i], 
                       testfs_inode_get_nr(in), testfs_inode_get_type(in), 
                       testfs_inode_get_size(in));
                testfs_put_inode(in);
        }
        return 0;
}
Ejemplo n.º 11
0
static int
testfs_ls(struct inode *in, int recursive)
{
        int offset = 0;
        struct dirent *d;

        for (; (d = testfs_next_dirent(in, &offset)); free(d)) {
                struct inode *cin;

                if (d->d_inode_nr < 0)
                        continue;
                cin = testfs_get_inode(testfs_inode_get_sb(in), d->d_inode_nr);
                printf("%s%s\n", D_NAME(d), 
                       (testfs_inode_get_type(cin) == I_DIR) ? "/":"");
                if (recursive && testfs_inode_get_type(cin) == I_DIR &&
                    (strcmp(D_NAME(d), ".") != 0) && 
                    (strcmp(D_NAME(d), "..") != 0)) {
                        testfs_ls(cin, recursive);
                }
                testfs_put_inode(cin);
        }
        return 0;
}