예제 #1
0
int op_chmod (const char *path, mode_t mode)
{
	int rt;
	int mask;
	time_t tm;
	ext2_ino_t ino;
	struct ext2_inode inode;
	ext2_filsys e2fs = current_ext2fs();

	debugf("enter");
	debugf("path = %s 0%o", path, mode);

	rt = do_check(path);
	if (rt != 0) {
		debugf("do_check(%s); failed", path);
		return rt;
	}

	rt = do_readinode(e2fs, path, &ino, &inode);
	if (rt) {
		debugf("do_readinode(%s, &ino, &vnode); failed", path);
		return rt;
	}

	tm = e2fs->now ? e2fs->now : time(NULL);
	mask = S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX;
	inode.i_mode = (inode.i_mode & ~mask) | (mode & mask);
	inode.i_ctime = tm;

	rt = do_writeinode(e2fs, ino, &inode);
	if (rt) {
		debugf("do_writeinode(e2fs, ino, &inode); failed");
		return -EIO;
	}

	debugf("leave");
	return 0;
}
예제 #2
0
int op_chown (const char *path, uid_t uid, gid_t gid)
{
	int rt;
	ext2_ino_t ino;
	struct ext2_inode inode;
	ext2_filsys e2fs = current_ext2fs();

	debugf("enter");
	debugf("path = %s", path);
	
	rt = do_check(path);
	if (rt != 0) {
		debugf("do_check(%s); failed", path);
		return rt;
	}

	rt = do_readinode(e2fs, path, &ino, &inode);
	if (rt) {
		debugf("do_readinode(%s, &ino, &vnode); failed", path);
		return rt;
	}
	
	if (uid != -1) {
		ext2_write_uid(&inode, uid);
	}
	if (gid != -1) {
		ext2_write_gid(&inode, gid);
	}

	rt = do_writeinode(e2fs, ino, &inode);
	if (rt) {
		debugf("do_writeinode(e2fs, ino, &inode); failed");
		return -EIO;
	}

	debugf("leave");
	return 0;
}
예제 #3
0
int op_unlink (const char *path)
{
	int rt;
	errcode_t rc;

	char *p_path;
	char *r_path;

	ext2_ino_t p_ino;
	struct ext2_inode p_inode;
	ext2_ino_t r_ino;
	struct ext2_vnode *r_vnode;
	struct ext2_inode *r_inode;

	ext2_filsys e2fs;
	FUSE_EXT2_LOCK;
	e2fs	= current_ext2fs();

	debugf("enter");
	debugf("path = %s", path);

	rt=do_check_split(path, &p_path, &r_path);
	if (rt != 0) {
		debugf("do_check_split: failed");
		goto err;
	}

	debugf("parent: %s, child: %s", p_path, r_path);

	rt = do_readinode(e2fs, p_path, &p_ino, &p_inode);
	if (rt) {
		debugf("do_readinode(%s, &p_ino, &p_inode); failed", p_path);
		goto err_free_split;
	}
	rt = do_readvnode(e2fs, path, &r_ino, &r_vnode, DONT_OPEN_FILE);
	if (rt) {
		debugf("do_readvnode(%s, &r_ino, &r_vnode); failed", path);
		goto err_free_split;
	}
	r_inode = vnode2inode(r_vnode);

	if(LINUX_S_ISDIR(r_inode->i_mode)) {
		debugf("%s is a directory", path);
		vnode_put(r_vnode,0);
		rt = -EISDIR;
		goto err_free_split;
	}

	rc = ext2fs_unlink(e2fs, p_ino, r_path, r_ino, 0);
	if (rc) {
		debugf("ext2fs_unlink(e2fs, %d, %s, %d, 0); failed", p_ino, r_path, r_ino);
		vnode_put(r_vnode,0);
		rt = -EIO;
		goto err_free_split;
	}

	if (r_inode->i_links_count > 0) {
		r_inode->i_links_count -= 1;
	}

	p_inode.i_ctime = p_inode.i_mtime = e2fs->now ? e2fs->now : time(NULL);

	rc = ext2fs_write_inode(e2fs, p_ino, &p_inode);
	if (rc) {
		debugf("ext2fs_write_inode(e2fs, p_ino, &p_inode); failed");
		vnode_put(r_vnode,1);
		rt = -EIO;
		goto err_free_split;
	}

	r_inode->i_ctime = e2fs->now ? e2fs->now : time(NULL);
	rc = vnode_put(r_vnode,1);
	if (rc) {
		debugf("vnode_put(r_vnode,1); failed");
		rt = -EIO;
		goto err_free_split;
	}

	free_split(p_path, r_path);
	debugf("leave");
	FUSE_EXT2_UNLOCK;
	return 0;
err_free_split:
	free_split(p_path, r_path);
err:
	FUSE_EXT2_UNLOCK;
	return rt;
}
예제 #4
0
int do_create (ext2_filsys e2fs, const char *path, mode_t mode, dev_t dev, const char *fastsymlink)
{
	int rt;
	time_t tm;
	errcode_t rc;

	char *p_path;
	char *r_path;

	ext2_ino_t ino;
	struct ext2_inode inode;
	ext2_ino_t n_ino;

	struct fuse_context *ctx;

	debugf("enter");
	debugf("path = %s, mode: 0%o", path, mode);

	rt=do_check_split(path, &p_path, &r_path);

	debugf("parent: %s, child: %s", p_path, r_path);

	rt = do_readinode(e2fs, p_path, &ino, &inode);
	if (rt) {
		debugf("do_readinode(%s, &ino, &inode); failed", p_path);
		free_split(p_path, r_path);
		return rt;
	}

	rc = ext2fs_new_inode(e2fs, ino, mode, 0, &n_ino);
	if (rc) {
		debugf("ext2fs_new_inode(ep.fs, ino, mode, 0, &n_ino); failed");
		return -ENOMEM;
	}

	do {
		debugf("calling ext2fs_link(e2fs, %d, %s, %d, %d);", ino, r_path, n_ino, do_modetoext2lag(mode));
		rc = ext2fs_link(e2fs, ino, r_path, n_ino, do_modetoext2lag(mode));
		if (rc == EXT2_ET_DIR_NO_SPACE) {
			debugf("calling ext2fs_expand_dir(e2fs, &d)", ino);
			if (ext2fs_expand_dir(e2fs, ino)) {
				debugf("error while expanding directory %s (%d)", p_path, ino);
				free_split(p_path, r_path);
				return -ENOSPC;
			}
		}
	} while (rc == EXT2_ET_DIR_NO_SPACE);
	if (rc) {
		debugf("ext2fs_link(e2fs, %d, %s, %d, %d); failed", ino, r_path, n_ino, do_modetoext2lag(mode));
		free_split(p_path, r_path);
		return -EIO;
	}

	if (ext2fs_test_inode_bitmap(e2fs->inode_map, n_ino)) {
		debugf("inode already set");
	}

	ext2fs_inode_alloc_stats2(e2fs, n_ino, +1, 0);
	memset(&inode, 0, sizeof(inode));
	tm = e2fs->now ? e2fs->now : time(NULL);
	inode.i_mode = mode;
	inode.i_atime = inode.i_ctime = inode.i_mtime = tm;
	inode.i_links_count = 1;
	inode.i_size = 0;
	ctx = fuse_get_context();
	if (ctx) {
		inode.i_uid = ctx->uid;
		inode.i_gid = ctx->gid;
	}

	if (S_ISCHR(mode) || S_ISBLK(mode)) {
		if (old_valid_dev(dev))
			inode.i_block[0]= ext2fs_cpu_to_le32(old_encode_dev(dev));
		else
			inode.i_block[1]= ext2fs_cpu_to_le32(new_encode_dev(dev));
	}

	if (S_ISLNK(mode) && fastsymlink != NULL) {
		inode.i_size = strlen(fastsymlink);
		strncpy((char *)&(inode.i_block[0]),fastsymlink,
				(EXT2_N_BLOCKS * sizeof(inode.i_block[0])));
	}

	rc = ext2fs_write_new_inode(e2fs, n_ino, &inode);
	if (rc) {
		debugf("ext2fs_write_new_inode(e2fs, n_ino, &inode);");
		free_split(p_path, r_path);
		return -EIO;
	}

	/* update parent dir */
	rt = do_readinode(e2fs, p_path, &ino, &inode);
	if (rt) {
		debugf("do_readinode(%s, &ino, &inode); dailed", p_path);
		free_split(p_path, r_path);
		return -EIO;
	}
	inode.i_ctime = inode.i_mtime = tm;
	rc = ext2fs_write_inode(e2fs, ino, &inode);
	if (rc) {
		debugf("ext2fs_write_inode(e2fs, ino, &inode); failed");
		free_split(p_path, r_path);
		return -EIO;
	}

	free_split(p_path, r_path);

	debugf("leave");
	return 0;
}
예제 #5
0
int op_link (const char *source, const char *dest)
{
    int rc;
    char *p_path;
    char *r_path;

    ext2_ino_t ino;
    ext2_ino_t d_ino;
    struct ext2_vnode *vnode;
    struct ext2_inode *inode;
    struct ext2_inode d_inode;
    ext2_filsys e2fs = current_ext2fs();

    debugf("source: %s, dest: %s", source, dest);

    rc = do_check(source);
    if (rc != 0) {
        debugf("do_check(%s); failed", source);
        return rc;
    }

    rc = do_check_split(dest, &p_path, &r_path);
    if (rc != 0) {
        debugf("do_check(%s); failed", dest);
        return rc;
    }

    debugf("parent: %s, child: %s", p_path, r_path);

    rc = do_readinode(e2fs, p_path, &d_ino, &d_inode);
    if (rc) {
        debugf("do_readinode(%s, &ino, &inode); failed", p_path);
        free_split(p_path, r_path);
        return rc;
    }

    rc = do_readvnode(e2fs, source, &ino, &vnode);
    if (rc) {
        debugf("do_readvnode(%s, &ino, &vnode); failed", source);
        free_split(p_path, r_path);
        return rc;
    }

    inode = vnode2inode(vnode);

    do {
        debugf("calling ext2fs_link(e2fs, %d, %s, %d, %d);", d_ino, r_path, ino, do_modetoext2lag(inode->i_mode));
        rc = ext2fs_link(e2fs, d_ino, r_path, ino, do_modetoext2lag(inode->i_mode));
        if (rc == EXT2_ET_DIR_NO_SPACE) {
            debugf("calling ext2fs_expand_dir(e2fs, &d)", d_ino);
            if (ext2fs_expand_dir(e2fs, d_ino)) {
                debugf("error while expanding directory %s (%d)", p_path, d_ino);
                vnode_put(vnode, 0);
                free_split(p_path, r_path);
                return -ENOSPC;
            }
        }
    } while (rc == EXT2_ET_DIR_NO_SPACE);
    if (rc) {
        debugf("ext2fs_link(e2fs, %d, %s, %d, %d); failed", d_ino, r_path, ino, do_modetoext2lag(inode->i_mode));
        vnode_put(vnode, 0);
        free_split(p_path, r_path);
        return -EIO;
    }

    d_inode.i_mtime = d_inode.i_ctime = inode->i_ctime = e2fs->now ? e2fs->now : time(NULL);
    inode->i_links_count += 1;
    rc=vnode_put(vnode,1);
    if (rc) {
        debugf("vnode_put(vnode,1); failed");
        free_split(p_path, r_path);
        return -EIO;
    }
    rc = ext2fs_write_inode(e2fs, d_ino, &d_inode);
    if (rc) {
        debugf("ext2fs_write_inode(e2fs, d_ino, &d_inode); failed");
        free_split(p_path, r_path);
        return -EIO;
    }
    debugf("done");

    return 0;
}
예제 #6
0
int op_readlink (const char *path, char *buf, size_t size)
{
	int rt;
	size_t s;
	errcode_t rc;
	ext2_ino_t ino;
	char *b = NULL;
	char *pathname;
	struct ext2_inode inode;
	ext2_filsys e2fs;
	FUSE_EXT2_LOCK;
	e2fs	= current_ext2fs();
	
	debugf("enter");
	debugf("path = %s", path);

	rt = do_readinode(e2fs, path, &ino, &inode);
	if (rt) {
		debugf("do_readinode(%s, &ino, &inode); failed", path);
		goto err;
	}
	
	if (!LINUX_S_ISLNK(inode.i_mode)) {
		debugf("%s is not a link", path);
		rt = -EINVAL;
		goto err;
	}
	
	if (ext2fs_inode_data_blocks(e2fs, &inode)) {
		rc = ext2fs_get_mem(EXT2_BLOCK_SIZE(e2fs->super), &b);
		if (rc) {
			debugf("ext2fs_get_mem(EXT2_BLOCK_SIZE(e2fs->super), &b); failed");
			rt = -ENOMEM;
			goto err;
		}
		rc = io_channel_read_blk(e2fs->io, inode.i_block[0], 1, b);
		if (rc) {
			ext2fs_free_mem(&b);
			debugf("io_channel_read_blk(e2fs->io, inode.i_block[0], 1, b); failed");
			rt = -EIO;
			goto err;
		}
		pathname = b;
	} else {
		pathname = (char *) &(inode.i_block[0]);
	}
	
	debugf("pathname: %s", pathname);
	
	s = (size < strlen(pathname) + 1) ? size : strlen(pathname) + 1;
	snprintf(buf, s, "%s", pathname);
	
	if (b) {
		ext2fs_free_mem(&b);
	}

	debugf("leave");
	FUSE_EXT2_UNLOCK;
	return 0;
err:
	FUSE_EXT2_UNLOCK;
	return rt;
}