Exemple #1
0
int op_chown (const char *path, uid_t uid, gid_t gid)
{
	int rt;
	int rc;
	ino_t ino;
	struct ufs_vnode *vnode;
	struct inode *inode;
	uufsd_t *ufs = current_ufs();

	RETURN_IF_RDONLY(ufs);

	debugf("enter");
	debugf("path = %s", path);
	
	rt = do_readvnode(ufs, path, &ino, &vnode);
	if (rt) {
		debugf("do_readvnode(%s, &ino, &vnode); failed", path);
		return rt;
	}
	inode = vnode2inode(vnode);
	
	if (uid != -1)
		inode->i_gid = gid;
	if (gid != -1)
		inode->i_uid = uid;

	rc=vnode_put(vnode,1);
	if (rc) {
		debugf("vnode_put(vnode,1); failed");
		return -EIO;
	}

	debugf("leave");
	return 0;
}
int do_killfilebyinode (uufsd_t *ufs, ino_t ino, struct ufs_vnode *vnode)
{
	int rc;
	debugf("enter");
	struct inode *inode = vnode2inode(vnode);

	inode->i_nlink = 0;

	if (inode->i_blocks) {
		ufs_truncate(ufs, vnode, 0);
	}

	rc = ufs_free_inode(ufs, vnode, ino, inode->i_mode);
	if (rc) {
		debugf("Unable to free inode\n");
		return -EIO;
	}

	ufs_clear_inode(vnode);
	rc = ufs_write_inode(ufs, ino, vnode);
	if (rc) {
		debugf("ufs_write_inode(ufs, ino, inode); failed");
		return -EIO;
	}

	debugf("leave");
	return 0;
}
Exemple #3
0
static int ufs_new_dir_block(uufsd_t *ufs, ino_t dir_ino,
		struct ufs_vnode *parent, char **block)
{
	struct direct 	*dir = NULL;
	int		retval;
	char			*buf;
	int			rec_len;
	struct fs *fs = &ufs->d_fs;
	int dirsize = DIRBLKSIZ;
	int blocksize = fragroundup(fs, dirsize);

	retval = ufs_get_mem(blocksize, &buf);
	if (retval)
		return retval;
	memset(buf, 0, blocksize);
	dir = (struct direct *) buf;

	//retval = ufs_set_rec_len(ufs, dirsize, dir);
	//if (retval)
		//return retval;

	if (dir_ino) {
		/*
		 * Set up entry for '.'
		 */
		dir->d_ino = dir_ino;
		dir->d_namlen = 1;
		dir->d_name[0] = '.';
		dir->d_type = DT_DIR;
		rec_len = dirsize - UFS_DIR_REC_LEN(1);
		dir->d_reclen = UFS_DIR_REC_LEN(1);

		/*
		 * Set up entry for '..'
		 */
		dir = (struct direct *) (buf + dir->d_reclen);
		//retval = ufs_set_rec_len(ufs, rec_len, dir);
		//if (retval)
			//return retval;
		dir->d_ino = vnode2inode(parent)->i_number;
		dir->d_namlen = 2;
		dir->d_name[0] = '.';
		dir->d_name[1] = '.';
		dir->d_type = DT_DIR;
		dir->d_reclen = rec_len;
	}
	*block = buf;
	return 0;
}
static void
ufs_clear_inode(struct ufs_vnode *vnode)
{
	struct inode *inode = vnode2inode(vnode);
	inode->i_size = 0;
	inode->i_mtime = inode->i_ctime = inode->i_atime = 0;
	inode->i_blocks = 0;
	inode->i_effnlink = 0;
	inode->i_count = 0;
	inode->i_endoff = 0;
	inode->i_diroff = 0;
	inode->i_offset = 0;
	inode->i_reclen = 0;
	inode->i_mode = 0;
	inode->i_nlink = 0;
	inode->i_flags = 0;
	inode->i_uid = 0;
	inode->i_gid = 0;
}
Exemple #5
0
int op_chown (const char *path, uid_t uid, gid_t gid)
{
	int rt;
	errcode_t rc;
	ext2_ino_t ino;
	struct ext2_vnode *vnode;
	struct ext2_inode *inode;
	ext2_filsys e2fs;
	FUSE_EXT2_LOCK;
	e2fs	= current_ext2fs();

	debugf("enter");
	debugf("path = %s", path);
	
	rt = do_readvnode(e2fs, path, &ino, &vnode, DONT_OPEN_FILE);
	if (rt) {
		debugf("do_readvnode(%s, &ino, &vnode); failed", path);
		goto err;
	}
	inode = vnode2inode(vnode);
	
	if (uid != -1)
		inode->i_gid = gid;
	if (gid != -1)
		inode->i_uid = uid;

	rc=vnode_put(vnode,1);
	if (rc) {
		debugf("vnode_put(vnode,1); failed");
		rt = -EIO;
		goto err;
	}
	rt = 0;

err:
	debugf("leave");
	FUSE_EXT2_UNLOCK;
	return rt;
}
int op_utimens (const char *path, const struct timespec tv[2])
{
	int rt;
	errcode_t rc;
	ext2_ino_t ino;
	struct ext2_vnode *vnode;
	struct ext2_inode *inode;
	ext2_filsys e2fs;
	FUSE_EXT2_LOCK;
	e2fs	= current_ext2fs();

	debugf("enter");
	debugf("path = %s", path);
	
	rt = do_readvnode(e2fs, path, &ino, &vnode, DONT_OPEN_FILE);
	if (rt) {
		debugf("do_readvnode(%s, &ino, &vnode); failed", path);
		FUSE_EXT2_UNLOCK;
		return rt;
	}
	inode = vnode2inode(vnode);
	
	inode->i_atime = tv[0].tv_sec;
	inode->i_mtime = tv[0].tv_sec;

	rc=vnode_put(vnode,1);
	if (rc) {
		debugf("vnode_put(vnode,1); failed");
		FUSE_EXT2_UNLOCK;
		return -EIO;
	}

	debugf("leave");
	FUSE_EXT2_UNLOCK;
	return 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;
}
Exemple #8
0
int ufs_dir_iterate(uufsd_t *ufs, ino_t dirino,
		    int (*func)(
					  struct direct *dirent,
					  int n,
					  char *buf,
					  void	*priv_data),
			      void *priv_data)
{
	int i, ret = 0;
	ufs2_daddr_t ndb;
	ufs2_daddr_t blkno;
	int blksize = ufs->d_fs.fs_bsize;
	u_int64_t dir_size;
	char *dirbuf = NULL;
	struct ufs_vnode *vnode;

	vnode = vnode_get(ufs, dirino);
	if (vnode == NULL) {
		ret = -ENOMEM;
		goto out;
	}
	dir_size = vnode2inode(vnode)->i_size;

	dirbuf = malloc(blksize);
	if (!dirbuf) {
		ret = -ENOMEM;
		goto out;
	}

	ndb = howmany(dir_size, ufs->d_fs.fs_bsize);
	int offset, pos = 0;
	for (i = 0; i < ndb ; i++) {
		ret = ufs_bmap(ufs, vnode, i, &blkno);
		if (ret) {
			ret = -EIO;
			goto out;
		}
		blksize = ufs_inode_io_size(vnode2inode(vnode), pos, 0);
		if (blkread(ufs, fsbtodb(&ufs->d_fs, blkno), dirbuf, blksize) == -1) {
			debugf("Unable to read block %d\n",blkno);
			ret = -EIO;
			goto out;
		}
		offset = 0;
		while (offset < blksize && pos + offset < dir_size) {
			struct direct *de = (struct direct *)(dirbuf + offset);

			/* HACK: Restrict frame for func() operations
			 *       to blocks of DIRBLKSIZ bytes
			 */
			int    blockoff = offset % DIRBLKSIZ;
			char * dirblock = dirbuf + (offset-blockoff);

			ret = (*func)(de, blockoff, dirblock, priv_data);
			if (ret & DIRENT_CHANGED) {
				if (blkwrite(ufs, fsbtodb(&ufs->d_fs, blkno), dirbuf, blksize) == -1) {
					debugf("Unable to write block %d\n",blkno);
					ret = -EIO;
					goto out;
				}
			}
			if (ret & DIRENT_ABORT) {
				ret = 0;
				goto out;
			}
			offset += de->d_reclen;
		}
		pos += blksize;
	}

out:
	if (vnode) {
		vnode_put(vnode, 0);
	}
	if (dirbuf) {
		free(dirbuf);
	}
	return ret;
}
Exemple #9
0
static int ufs_mkdir(uufsd_t *ufs, ino_t parent, ino_t inum, char *name)
{
	int		retval;
	struct ufs_vnode	*parent_vnode = NULL, *vnode = NULL;
	struct inode *parent_inode, *inode;
	ino_t		ino = inum;
	ino_t		scratch_ino;
	ufs2_daddr_t		blk;
	char			*block = 0;
	struct fs *fs = &ufs->d_fs;
	int dirsize = DIRBLKSIZ;
	int blocksize = fragroundup(fs, dirsize);

	parent_vnode = vnode_get(ufs, parent);
	if (!parent_vnode) {
		return ENOENT;
	}

	parent_inode = vnode2inode(parent_vnode);
	/*
	 * Allocate an inode, if necessary
	 */
	if (!ino) {
		retval = ufs_valloc(parent_vnode, DTTOIF(DT_DIR), &vnode);
		if (retval)
			goto cleanup;
		ino = vnode->inode.i_number;
		inode = vnode2inode(vnode);
	}

	/*
	 * Allocate a data block for the directory
	 */
	retval = ufs_block_alloc(ufs, inode, fragroundup(fs, dirsize), &blk);
	if (retval)
		goto cleanup;

	/*
	 * Create a scratch template for the directory
	 */
	retval = ufs_new_dir_block(ufs, vnode->inode.i_number, parent_vnode, &block);
	if (retval)
		goto cleanup;

	/*
	 * Get the parent's inode, if necessary
	if (parent != ino) {
		parent_vnode = vnode_get(ufs, parent);
		if (retval)
			goto cleanup;
	} else
		memset(&parent_inode, 0, sizeof(parent_inode));
	 */

	/*
	 * Create the inode structure....
	 */
	inode->i_mode = DT_DIR | (0777);
	inode->i_uid = inode->i_gid = 0;
	UFS_DINODE(inode)->di_db[0] = blk;
	inode->i_nlink = 1;
	inode->i_size = dirsize;

	/*
	 * Write out the inode and inode data block
	 */
	retval = blkwrite(ufs, fsbtodb(fs, blk), block, blocksize);
	if (retval == -1)
		goto cleanup;

	/*
	 * Link the directory into the filesystem hierarchy
	 */
	if (name) {
		retval = ufs_lookup(ufs, parent, name, strlen(name),
				       &scratch_ino);
		if (!retval) {
			retval = EEXIST;
			name = 0;
			goto cleanup;
		}
		if (retval != ENOENT)
			goto cleanup;
		retval = ufs_link(ufs, parent, name, vnode, DTTOIF(DT_DIR));
		if (retval)
			goto cleanup;
	}

	/*
	 * Update parent inode's counts
	 */
	if (parent != ino) {
		parent_inode->i_nlink++;
	}

cleanup:
	if (vnode)
		vnode_put(vnode, 1);

	if (parent_vnode)
		vnode_put(parent_vnode, 1);
	if (block)
		ufs_free_mem(&block);
	return retval;


}
Exemple #10
0
int op_mkdir (const char *path, mode_t mode)
{
	int rt;
	time_t tm;

	char *p_path;
	char *r_path;

	ino_t ino;
	struct ufs_vnode *vnode;
	struct ufs_vnode *child_vnode;
	struct inode *inode;

	struct fuse_context *ctx;

	uufsd_t *ufs = current_ufs();

	RETURN_IF_RDONLY(ufs);

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

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

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

	rt = do_readvnode(ufs, p_path, &ino, &vnode);
	if (!vnode) {
		debugf("do_readvnode(%s, &ino, &vnode); failed", p_path);
		free_split(p_path, r_path);
		return rt;
	}

	debugf("calling ufs_mkdir(ufs, %d, 0, %s);", ino, r_path);
	rt = ufs_mkdir(ufs, ino, 0, r_path);
	if (rt) {
		debugf("ufs_mkdir(ufs, %d, 0, %s); failed (%d)", ino, r_path, rt);
		free_split(p_path, r_path);
		return rt;
	}

	rt = do_readvnode(ufs, path, &ino, &child_vnode);
	if (rt) {
		debugf("do_readvnode(%s, &ino, &child_vnode); failed", path);
		return -EIO;
	}
	tm = ufs->now ? ufs->now : time(NULL);
	inode = vnode2inode(child_vnode);
	inode->i_mode = S_IFDIR | mode;
	inode->i_ctime = inode->i_atime = inode->i_mtime = tm;
	ctx = fuse_get_context();
	if (ctx) {
		inode->i_uid = ctx->uid;
		inode->i_gid = ctx->gid;
	}

	vnode_put(child_vnode, 1);

	inode = vnode2inode(vnode);
	inode->i_ctime = inode->i_mtime = tm;

	vnode_put(vnode, 1);

	free_split(p_path, r_path);

	debugf("leave");
	return 0;
}
Exemple #11
0
int op_link (const char *source, const char *dest)
{
	int rc;
	char *p_path;
	char *r_path;
	ino_t d_ino, ino;
	struct ufs_vnode *vnode;
	struct inode *inode;
	uufsd_t *ufs = current_ufs();

	RETURN_IF_RDONLY(ufs);

	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_readvnode(ufs, p_path, &d_ino, &vnode);
	if (rc) {
		debugf("do_readvnode(%s, &d_ino, &inode); failed", p_path);
		free_split(p_path, r_path);
		return rc;
	}

	vnode_put(vnode, 0);

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

	inode = vnode2inode(vnode);

	rc = ufs_link(ufs, d_ino, r_path, vnode, inode->i_mode);
	if (rc) {
		debugf("ufs_link() failed");
		vnode_put(vnode, 0);
		free_split(p_path, r_path);
		return rc;
	}

	inode->i_mtime = inode->i_atime = inode->i_ctime = ufs->now ? ufs->now : time(NULL);
	rc = vnode_put(vnode, 1);
	if (rc) {
		debugf("vnode_put(vnode,1); failed");
		free_split(p_path, r_path);
		return -EIO;
	}
	debugf("done");

	return 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;
}
Exemple #13
0
int op_unlink (const char *path)
{
	int rt;

	char *p_path;
	char *r_path;

	ino_t p_ino;
	struct ufs_vnode *p_vnode;
	ino_t r_ino;
	struct ufs_vnode *r_vnode;
	struct inode *r_inode;
	struct inode *p_inode;

	uufsd_t *ufs = current_ufs();

	RETURN_IF_RDONLY(ufs);

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

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

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

	rt = do_readvnode(ufs, p_path, &p_ino, &p_vnode);
	if (rt) {
		debugf("do_readinode(%s, &p_ino, &p_inode); failed", p_path);
		free_split(p_path, r_path);
		return rt;
	}
	rt = do_readvnode(ufs, path, &r_ino, &r_vnode);
	if (rt) {
		debugf("do_readvnode(%s, &r_ino, &r_vnode); failed", path);
		free_split(p_path, r_path);
		return rt;

	}
	r_inode = vnode2inode(r_vnode);

	if(S_ISDIR(r_inode->i_mode)) {
		debugf("%s is a directory", path);
		vnode_put(r_vnode, 0);
		free_split(p_path, r_path);
		return -EISDIR;
	}

	rt = ufs_unlink(ufs, p_ino, r_path, r_ino, 0);
	if (rt) {
		debugf("ufs_unlink(ufs, %d, %s, %d, 0); failed", p_ino, r_path, r_ino);
		vnode_put(r_vnode, 0);
		vnode_put(p_vnode, 0);
		free_split(p_path, r_path);
		return -EIO;
	}

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

	p_inode = vnode2inode(p_vnode);
	p_inode->i_ctime = p_inode->i_mtime = ufs->now ? ufs->now : time(NULL);
	rt = vnode_put(p_vnode, 1);
	if (rt) {
		debugf("ufs_write_inode(ufs, p_ino, &p_inode); failed");
		vnode_put(r_vnode,1);
		free_split(p_path, r_path);
		return -EIO;
	}

	r_inode->i_ctime = ufs->now ? ufs->now : time(NULL);
	rt = vnode_put(r_vnode, 1);
	if (rt) {
		debugf("vnode_put(r_vnode, 1); failed");
		free_split(p_path, r_path);
		return -EIO;
	}

	free_split(p_path, r_path);
	debugf("leave");
	return 0;
}