예제 #1
0
파일: super.c 프로젝트: shehbazj/fslice
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;
}
예제 #2
0
파일: dir.c 프로젝트: pgoodman/testfs
/* return 0 on success.
 * return negative value on error. */
static int
testfs_add_dirent(struct inode *dir, char *name, int inode_nr)
{
        struct dirent *d;
        int p_offset = 0, offset = 0;
        int found = 0;
        int ret = 0;
        int len = strlen(name) + 1;
        fslice_name(name, len);

        assert(dir);
        assert(testfs_inode_get_type(dir) == I_DIR);
        assert(name);
        for (; ret == 0 && found == 0; free(d)) {
                p_offset = offset;
                if ((d = testfs_next_dirent(dir, &offset)) == NULL)
                        break;
                if ((d->d_inode_nr >= 0) && (strcmp(D_NAME(d), name) == 0)) {
                        ret = -EEXIST;
                        continue;
                }
                if ((d->d_inode_nr >= 0) || (d->d_name_len != len))
                        continue;
                found = 1;
        }
        if (ret < 0)
                return ret;
        assert(found || (p_offset == testfs_inode_get_size(dir)));
        return testfs_write_dirent(dir, name, len, inode_nr, p_offset);
}
예제 #3
0
파일: dir.c 프로젝트: pgoodman/testfs
/* allocates memory, caller should free */
struct dirent *
testfs_next_dirent(struct inode *dir, int *offset)
{
        int ret;
        struct dirent d, *dp;

        assert(dir);
        assert(testfs_inode_get_type(dir) == I_DIR);
        if (*offset >= testfs_inode_get_size(dir))
                return NULL;
        ret = testfs_read_data(dir, *offset, (char *)&d, sizeof(struct dirent));
        if (ret < 0)
                return NULL;
        assert(d.d_name_len > 0);
        dp = malloc(sizeof(struct dirent) + d.d_name_len);
        if (!dp)
                return NULL;
        *dp = d;
        *offset += sizeof(struct dirent);
        ret = testfs_read_data(dir, *offset, D_NAME(dp), d.d_name_len);
        if (ret < 0) {
                free(dp);
                return NULL;
        }
        *offset += d.d_name_len;
        return dp;
}
예제 #4
0
파일: file.c 프로젝트: pgoodman/testfs
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;
}
예제 #5
0
파일: dir.c 프로젝트: pgoodman/testfs
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;
}
예제 #6
0
파일: dir.c 프로젝트: pgoodman/testfs
/* returns dirent associated with inode_nr in dir.
 * returns NULL on error.
 * allocates memory, caller should free. */
static struct dirent *
testfs_find_dirent(struct inode *dir, int inode_nr)
{
        struct dirent *d;
        int offset = 0;

        assert(dir);
        assert(testfs_inode_get_type(dir) == I_DIR);
        assert(inode_nr >= 0);
        for (; (d = testfs_next_dirent(dir, &offset)); free(d)) {
                if (d->d_inode_nr == inode_nr)
                        return d;
        }
        return NULL;
}
예제 #7
0
파일: dir.c 프로젝트: pgoodman/testfs
static int
testfs_create_empty_dir(struct super_block *sb, int p_inode_nr,
                        struct inode *cdir)
{
        int ret;

        assert(testfs_inode_get_type(cdir) == I_DIR);
        ret = testfs_add_dirent(cdir, ".", testfs_inode_get_nr(cdir));
        if (ret < 0)
                return ret;
        ret = testfs_add_dirent(cdir, "..", p_inode_nr);
        if (ret < 0) {
                testfs_remove_dirent(sb, cdir, ".");
                return ret;
        }
        return 0;
}
예제 #8
0
파일: dir.c 프로젝트: jacksun007/testfs
/* returns negative value if name is not found */
int
testfs_dir_name_to_inode_nr(struct inode *dir, char *name)
{
        struct dirent *d;
        int offset = 0;
        int ret = -ENOENT;

        assert(dir);
        assert(name);
        assert(testfs_inode_get_type(dir) == I_DIR);
        for (; ret < 0 && (d = testfs_next_dirent(dir, &offset)); free(d)) {
                if ((d->d_inode_nr < 0) || (strcmp(D_NAME(d), name) != 0))
                        continue;
                ret = d->d_inode_nr;
        }
        return ret;
}
예제 #9
0
파일: file.c 프로젝트: pgoodman/testfs
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;
}
예제 #10
0
파일: dir.c 프로젝트: pgoodman/testfs
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;
}
예제 #11
0
파일: dir.c 프로젝트: pgoodman/testfs
/* 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;
}
예제 #12
0
파일: dir.c 프로젝트: pgoodman/testfs
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;
}