Example #1
0
/* returns inode_nr of dirent removed.
   returns negative value if name is not found */
static int
testfs_remove_dirent(struct super_block *sb, struct inode *dir, char *name)
{
        struct dirent *d;
        int p_offset, offset = 0;
        int inode_nr = -1;
        int ret = -ENOENT;

        assert(dir);
        assert(name);
        if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
                return -EINVAL;
        }
        for (; inode_nr == -1; free(d)) {
                p_offset = offset;
                if ((d = testfs_next_dirent(dir, &offset)) == NULL)
                        break;
                //fslice_name(D_NAME(d), d->d_name_len);
                if ((d->d_inode_nr < 0) || (strcmp(D_NAME(d), name) != 0))
                        continue;
                /* found the dirent */
                inode_nr = d->d_inode_nr;
                if ((ret = testfs_remove_dirent_allowed(sb, inode_nr)) < 0)
                        continue; /* this will break out of the loop */
                d->d_inode_nr = -1;
                ret = testfs_write_data(dir, p_offset, (char *)d, 
                                        sizeof(struct dirent) + d->d_name_len);
                if (ret >= 0)
                        ret = inode_nr;
        }
        return ret;
}
Example #2
0
/* 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);
}
Example #3
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;
}
Example #4
0
/* 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;
}
Example #5
0
/* 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;
}
Example #6
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;
}
Example #7
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;
}