Beispiel #1
0
int
fs_rmdir(const char *path)
{
	struct inode *dir;
	struct dirent *dent;
	uint32_t nblock, i, j;
	char *blk;
	int r;

	if ((r = inode_open(path, &dir)) < 0)
		return r;
	if (dir == diskaddr(super->s_root))
		return -EPERM;
	if (!S_ISDIR(dir->i_mode))
		return -ENOTDIR;

	nblock = dir->i_size / BLKSIZE;
	for (i = 0; i < nblock; i++) {
		if ((r = inode_get_block(dir, i, &blk)) < 0)
			return r;
		dent = (struct dirent *)blk;
		for (j = 0; j < BLKDIRENTS; ++j)
			if (dent[j].d_name[0] != '\0')
				return -ENOTEMPTY;
	}
	return inode_unlink(path);
}
Beispiel #2
0
// Writes an inode to disk.
static void inode_write(unsigned int inode_n, inode * n){
	unsigned int locin_block_index	= inode_get_block_index(inode_n);
	unsigned int real_block_index	= inode_get_block(inode_n);
	
	block b;
	block_clear(&b);
	block_read((void *)&b, real_block_index);
	
	inode * inodes = (inode *) &b;
	
	int i = 0;
	for (; i < FS_INODE_SIZE / sizeof(int); i++) {
		((int *)&inodes[locin_block_index])[i] = ((int*)n)[i];
	}
	block_write((void *)&b, real_block_index);
}
Beispiel #3
0
int
fs_readlink(const char *path, char *target, size_t len)
{
	struct inode *ino;
	size_t copylen;
	char *blk;
	int r;

	if ((r = inode_open(path, &ino)) < 0)
		return r;
	if ((r = inode_get_block(ino, 0, &blk)) < 0)
		return r;
	copylen = MIN(ino->i_size, len - 1);
	memcpy(target, blk, copylen);
	target[copylen] = '\0';

	return 0;
}
Beispiel #4
0
int
fs_symlink(const char *dstpath, const char *srcpath)
{
	struct inode *ino;
	struct fuse_context *ctxt;
	time_t curtime;
	size_t dstlen;
	char *blk;
	int r;

	if ((dstlen = strlen(dstpath)) >= PATH_MAX)
		return -ENAMETOOLONG;
	if ((r = inode_create(srcpath, &ino)) < 0) {
		return r;
	}
	ino->i_size = dstlen;
	ino->i_mode = S_IFLNK | 0777;
	ino->i_nlink = 1;

	curtime = time(NULL);
	ino->i_atime = curtime;
	ino->i_ctime = curtime;
	ino->i_mtime = curtime;

	ctxt = fuse_get_context();
	ino->i_owner = ctxt->uid;
	ino->i_group = ctxt->gid;

	if ((r = inode_get_block(ino, 0, &blk)) < 0) {
		inode_unlink(srcpath);
		return r;
	}
	memcpy(blk, dstpath, dstlen);
	inode_flush(ino);

	return 0;
}
Beispiel #5
0
void
fs_test(void)
{
	struct inode *ino, *ino2;
	int r;
	char *blk;
	uint32_t bits[4096];

	// back up bitmap
	memmove(bits, bitmap, 4096);
	// allocate block
	if ((r = alloc_block()) < 0)
		panic("alloc_block: %s", strerror(-r));
	// check that block was free
	assert(bits[r/32] & (1 << (r%32)));
	// and is not free any more
	assert(!(bitmap[r/32] & (1 << (r%32))));
	free_block(r);
	printf("alloc_block is good\n");

	if ((r = inode_open("/not-found", &ino)) < 0 && r != -ENOENT)
		panic("inode_open /not-found: %s", strerror(-r));
	else if (r == 0)
		panic("inode_open /not-found succeeded!");
	if ((r = inode_open("/msg", &ino)) < 0)
		panic("inode_open /msg: %s", strerror(-r));
	printf("inode_open is good\n");

	if ((r = inode_get_block(ino, 0, &blk)) < 0)
		panic("inode_get_block: %s", strerror(-r));
	if (strcmp(blk, msg) != 0)
		panic("inode_get_block returned wrong data");
	printf("inode_get_block is good\n");

	if ((r = inode_set_size(ino, 0)) < 0)
		panic("inode_set_size: %s", strerror(-r));
	assert(ino->i_direct[0] == 0);
	printf("inode_truncate is good\n");

	if ((r = inode_set_size(ino, strlen(msg))) < 0)
		panic("inode_set_size 2: %s", strerror(-r));
	if ((r = inode_get_block(ino, 0, &blk)) < 0)
		panic("inode_get_block 2: %s", strerror(-r));
	strcpy(blk, msg);
	printf("file rewrite is good\n");

	if ((r = inode_link("/msg", "/linkmsg")) < 0)
		panic("inode_link /msg /linkmsg: %s", strerror(-r));
	if ((r = inode_open("/msg", &ino)) < 0)
		panic("inode_open /msg: %s", strerror(-r));
	if ((r = inode_open("/linkmsg", &ino2)) < 0)
		panic("inode_open /linkmsg: %s", strerror(-r));
	if (ino != ino2)
		panic("linked files do not point to same inode");
	if (ino->i_nlink != 2)
		panic("link count incorrect: %u, expected 2", ino->i_nlink);
	printf("inode_link is good\n");

	if ((r = inode_unlink("/linkmsg")) < 0)
		panic("inode_unlink /linkmsg: %s", strerror(-r));
	if ((r = inode_open("/linkmsg", &ino2)) < 0 && r != -ENOENT)
		panic("inode_open /linkmsg after unlink: %s", strerror(-r));
	else if (r == 0)
		panic("inode_open /linkmsg after unlink succeeded!");
	if ((r = inode_open("/msg", &ino)) < 0)
		panic("inode_open /msg after /linkmsg unlinked: %s", strerror(-r));
	if (ino->i_nlink != 1)
		panic("link count incorrect: %u, expected 1", ino->i_nlink);
	printf("inode_unlink is good\n");
}