Esempio n. 1
0
static void serve_readlink(fuse_req_t req, fuse_ino_t ino)
{
	Dprintf("%s(ino = %lu)\n", __FUNCTION__, ino);
	bool symlink_supported = feature_supported(reqcfs(req), FSTITCH_FEATURE_SYMLINK);
	char link_name[PATH_MAX + 1];
	int r;

	if (!symlink_supported)
	{
		r = fuse_reply_err(req, ENOSYS);
		fuse_reply_assert(!r);
		return;
	}

	r = CALL(reqcfs(req), get_metadata, fusecfsino(req, ino), FSTITCH_FEATURE_SYMLINK, sizeof(link_name) - 1, link_name);
	if (r < 0)
	{
		r = fuse_reply_err(req, -r);
		fuse_reply_assert(!r);
		return;
	}
	link_name[r] = '\0';

	r = fuse_reply_readlink(req, link_name);
	fuse_reply_assert(!r);
}
Esempio n. 2
0
static int zfsfuse_readlink(fuse_req_t req, fuse_ino_t ino)
{
	vfs_t *vfs = (vfs_t *) fuse_req_userdata(req);
	zfsvfs_t *zfsvfs = vfs->vfs_data;

	ZFS_ENTER(zfsvfs);

	znode_t *znode;

	int error = zfs_zget(zfsvfs, ino, &znode, B_FALSE);
	if(error) {
		ZFS_EXIT(zfsvfs);
		/* If the inode we are trying to get was recently deleted
		   dnode_hold_impl will return EEXIST instead of ENOENT */
		return error == EEXIST ? ENOENT : error;
	}

	ASSERT(znode != NULL);
	vnode_t *vp = ZTOV(znode);
	ASSERT(vp != NULL);

	char buffer[PATH_MAX + 1];

	iovec_t iovec;
	uio_t uio;
	uio.uio_iov = &iovec;
	uio.uio_iovcnt = 1;
	uio.uio_segflg = UIO_SYSSPACE;
	uio.uio_fmode = 0;
	uio.uio_llimit = RLIM64_INFINITY;
	iovec.iov_base = buffer;
	iovec.iov_len = sizeof(buffer) - 1;
	uio.uio_resid = iovec.iov_len;
	uio.uio_loffset = 0;

	cred_t cred;
	zfsfuse_getcred(req, &cred);

	error = VOP_READLINK(vp, &uio, &cred, NULL);

	VN_RELE(vp);
	ZFS_EXIT(zfsvfs);

	if(!error) {
		VERIFY(uio.uio_loffset < sizeof(buffer));
		buffer[uio.uio_loffset] = '\0';
		fuse_reply_readlink(req, buffer);
	}

	return error;
}
Esempio n. 3
0
static void lo_readlink(fuse_req_t req, fuse_ino_t ino)
{
	char buf[PATH_MAX + 1];
	int res;

	res = readlinkat(lo_fd(req, ino), "", buf, sizeof(buf));
	if (res == -1)
		return (void) fuse_reply_err(req, errno);

	if (res == sizeof(buf))
		return (void) fuse_reply_err(req, ENAMETOOLONG);

	buf[res] = '\0';

	fuse_reply_readlink(req, buf);
}
Esempio n. 4
0
static void sqfs_ll_op_readlink(fuse_req_t req, fuse_ino_t ino) {
	char *dst;
	size_t size;
	sqfs_ll_i lli;
	if (sqfs_ll_iget(req, &lli, ino))
		return;
	
	if (!S_ISLNK(lli.inode.base.mode)) {
		fuse_reply_err(req, EINVAL);
	} else if (sqfs_readlink(&lli.ll->fs, &lli.inode, NULL, &size)) {
		fuse_reply_err(req, EIO);
	} else if (!(dst = malloc(size))) {
		fuse_reply_err(req, ENOMEM);
	} else if (sqfs_readlink(&lli.ll->fs, &lli.inode, dst, &size)) {
		fuse_reply_err(req, EIO);
		free(dst);
	} else {
		fuse_reply_readlink(req, dst);
		free(dst);
	}
}
static void workspace_nfs_readlink(fuse_req_t req, struct entry_struct *entry, struct call_info_struct *call_info)
{
    struct resource_struct *resource=call_info->object->resource;
    struct net_nfs_export_struct *nfs_export=(struct net_nfs_export_struct *) resource->data;
    struct nfs_context *nfs_ctx=(struct nfs_context *) nfs_export->data;
    char *path=call_info->pathinfo.path + call_info->relpath;
    int result=0;
    int len=512;
    char buffer[len];

    if (strlen(path)==0) path=(char *) rootpath;

    logoutput("workspace_nfs_readlink, path %s", path);

    /*
	TODO: make this buffer variable, only how to correct that?
	what error gives nfs_readlink back when buffer is too small?
    */

    pthread_mutex_lock(&nfs_export->mutex);

    result=nfs_readlink(nfs_ctx, path, buffer, len);

    pthread_mutex_unlock(&nfs_export->mutex);

    if (result<0) {

	logoutput("workspace_nfs_readlink, error reading readlink of %s, error %i:%s", path, abs(result), nfs_get_error(nfs_ctx));

	fuse_reply_err(req, abs(result));

    } else {

	fuse_reply_readlink(req, buffer);

    }

    free_path_pathinfo(&call_info->pathinfo);

}
Esempio n. 6
0
void hsx_fuse_readlink(fuse_req_t req, fuse_ino_t ino)
{
	int st = 0;
	int err = 0;
	struct hsfs_inode *hi = NULL;
	struct hsfs_super *hi_sb = NULL;
	char *link = NULL;
	DEBUG_IN("%s\n","THE HSX_FUSE_READLINK.");

	hi_sb = fuse_req_userdata(req);
	if(!hi_sb){
		ERR("%s gets inode->sb fails \n", progname);
		err = ENOENT;
		goto out;
	}
	hi = hsfs_ilookup(hi_sb, ino);
	if(!hi){
		ERR("%s gets inode fails \n", progname);
		err = ENOENT;
		goto out;
	}
	st = hsi_nfs3_readlink(hi,&link);
	if(st != 0){
		err = st;
		goto out;
	}
	fuse_reply_readlink(req, link);

out:
	if(link != NULL){
		free(link);
	}
	if(st != 0){
		fuse_reply_err(req, err);
	}
	DEBUG_OUT(" WITH ERRNO %d\n", err);
	return;
}
Esempio n. 7
0
static void overlay_readlink(fuse_req_t req, struct entry_struct *entry, struct call_info_struct *call_info)
{
    struct resource_struct *resource=call_info->object->resource;
    struct localfile_struct *localfile=(struct localfile_struct *) resource->data;
    struct pathinfo_struct *pathinfo=&call_info->pathinfo;
    unsigned int len0=pathinfo->len - call_info->relpath, len1=localfile->pathinfo.len;
    char path[len0 + len1 + 1];
    char *buff=NULL;
    size_t size=512;
    unsigned int error=0;

    memcpy(path, localfile->pathinfo.path, len1);

    if (len0>0) {

	memcpy(path+len1, pathinfo->path + call_info->relpath, len0);
	len1+=len0;

    }

    path[len1]='\0';

    logoutput("overlayfs_readlink: path %s", call_info->pathinfo.path);

    while(size<=PATH_MAX) {
	ssize_t lenread=0;

	if (buff) {

	    buff = realloc(buff, size);

	} else {

	    buff = malloc(size);

	}

	if ( buff ) {

    	    if ((lenread=readlink(path, buff, size))==-1) {

		error=errno;

		free(buff);
		goto out;

	    }

	    if (lenread < size) {

		/* success */

		buff[lenread] = '\0';
		fuse_reply_readlink(req, buff);

		free(buff);
		free_path_pathinfo(&call_info->pathinfo);

		return;

	    }

	    size+=512;

	    if (size>PATH_MAX) {

		error=ENAMETOOLONG;
		break;

	    }

	} else {

	    error=ENOMEM;
	    break;

	}

    }

    out:

    logoutput("overlayfs_readlink: error %i", error);

    fuse_reply_err(req, error);

    free_path_pathinfo(&call_info->pathinfo);

}