示例#1
0
void mfs_meta_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) {
	pathbuf *pathinfo;
	const uint8_t *path;
	//size_t pleng;
	int status;
//	if (ino==MASTER_INODE) {
//		minfo *masterinfo;
//		status = fs_direct_connect();
//		if (status<0) {
//			fuse_reply_err(req,EIO);
//			return;
//		}
//		masterinfo = malloc(sizeof(minfo));
//		if (masterinfo==NULL) {
//			fuse_reply_err(req,ENOMEM);
//			return;
//		}
//		masterinfo->sd = status;
//		masterinfo->sent = 0;
//		fi->direct_io = 1;
//		fi->fh = (unsigned long)masterinfo;
//		fuse_reply_open(req, fi);
//		return;
//	}
	if (ino==MASTERINFO_INODE) {
		fi->fh = 0;
		fi->direct_io = 0;
		fi->keep_cache = 1;
		fuse_reply_open(req, fi);
		return;
	}
	if ((ino & INODE_TYPE_MASK) == INODE_TYPE_TRASH) {
		status = fs_gettrashpath((ino&INODE_VALUE_MASK),&path);
		status = mfs_errorconv(status);
		if (status!=0) {
			fuse_reply_err(req, status);
		} else {
			pathinfo = malloc(sizeof(pathbuf));
			pthread_mutex_init(&(pathinfo->lock),NULL);
			pathinfo->changed = 0;
			pathinfo->size = strlen((char*)path)+1;
			pathinfo->p = malloc(pathinfo->size);
			memcpy(pathinfo->p,path,pathinfo->size-1);
			pathinfo->p[pathinfo->size-1]='\n';
			fi->direct_io = 1;
			fi->fh = (unsigned long)pathinfo;
			if (fuse_reply_open(req,fi) == -ENOENT) {
				fi->fh = 0;
				pthread_mutex_destroy(&(pathinfo->lock));
				free(pathinfo->p);
				free(pathinfo);
			}
		}
	} else {
		fuse_reply_err(req, EACCES);
	}
}
示例#2
0
文件: ll.c 项目: ksperling/squashfuse
static void sqfs_ll_op_open(fuse_req_t req, fuse_ino_t ino,
		struct fuse_file_info *fi) {
	sqfs_inode *inode;
	sqfs_ll *ll;
	
	if (fi->flags & (O_WRONLY | O_RDWR)) {
		fuse_reply_err(req, EROFS);
		return;
	}
	
	inode = malloc(sizeof(sqfs_inode));
	if (!inode) {
		fuse_reply_err(req, ENOMEM);
		return;
	}
	
	ll = fuse_req_userdata(req);
	if (sqfs_ll_inode(ll, inode, ino)) {
		fuse_reply_err(req, ENOENT);
	} else if (!S_ISREG(inode->base.mode)) {
		fuse_reply_err(req, EISDIR);
	} else {
		fi->fh = (intptr_t)inode;
		fuse_reply_open(req, fi);
		return;
	}
	free(inode);
}
示例#3
0
void blob_ll_open(fuse_req_t req, fuse_ino_t ino,
		    struct fuse_file_info *fi) {
    if (ino_id(ino) == 0 || ino_version(ino) == 0) {
	fuse_reply_err(req, EISDIR);
	return;
    }

    oh_pool_t::pobject_t blob_handler = oh_pool->acquire();
    if (!blob_handler) {
	fuse_reply_err(req, EMFILE);
	return; 
    }
    if (!blob_handler->get_latest(ino_id(ino))) {
	oh_pool->release(blob_handler);
	fuse_reply_err(req, EIO);
	return;
    }
    blob_mirror_t *lm = NULL;
    fi->fh = (boost::uint64_t)NULL;
    try {
	lm = new blob_mirror_t(blob_handler, ino_version(ino));
	fi->fh = (boost::uint64_t)lm;
    } catch(std::exception &e) {
	ERROR(e.what());
	oh_pool->release(blob_handler);
	delete lm;
	fuse_reply_err(req, EIO);
	return;
    }
    fuse_reply_open(req, fi);
}
示例#4
0
static void serve_open(fuse_req_t req, fuse_ino_t fuse_ino,
                       struct fuse_file_info * fi)
{
	Dprintf("%s(ino = %lu)\n", __FUNCTION__, fuse_ino);
	inode_t cfs_ino;
	uint32_t type;
	fdesc_t * fdesc;
	int r;

//	else if ((fi->flags & 3) != O_RDONLY)
//		fuse_reply_err(req, EACCES);

	cfs_ino = fusecfsino(req, fuse_ino);

	r = CALL(reqcfs(req), get_metadata, cfs_ino, FSTITCH_FEATURE_FILETYPE, sizeof(type), &type);
	assert(r == sizeof(type));

	if (type == TYPE_DIR)
	{
		r = fuse_reply_err(req, EISDIR);
		fuse_reply_assert(!r);
		return;
	}

	r = CALL(reqcfs(req), open, cfs_ino, 0, &fdesc);
	assert(r >= 0);
	fi_set_fdesc(fi, fdesc);
	
	r = fuse_reply_open(req, fi);
	fuse_reply_assert(!r);
}
示例#5
0
static void lo_opendir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
{
	int error = ENOMEM;
	struct lo_dirp *d = calloc(1, sizeof(struct lo_dirp));
	if (d == NULL)
		goto out_err;

	d->fd = openat(lo_fd(req, ino), ".", O_RDONLY);
	if (d->fd == -1)
		goto out_errno;

	d->dp = fdopendir(d->fd);
	if (d->dp == NULL)
		goto out_errno;

	d->offset = 0;
	d->entry = NULL;

	fi->fh = (uintptr_t) d;
	fuse_reply_open(req, fi);
	return;

out_errno:
	error = errno;
out_err:
	if (d) {
		if (d->fd != -1)
			close(d->fd);
		free(d);
	}
	fuse_reply_err(req, error);
}
static void workspace_nfs_open(fuse_req_t req, struct workspace_fh_struct *fh)
{
    struct resource_struct *resource=fh->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=fh->pathinfo.path + fh->relpath;
    struct nfsfh *nfsfh=NULL;
    int result=0;

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

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

    pthread_mutex_lock(&nfs_export->mutex);

    result=nfs_open(nfs_ctx, path, fh->flags, &nfsfh);

    pthread_mutex_unlock(&nfs_export->mutex);

    if (result==0) {

	fh->handle.data=(void *) nfsfh;
	fuse_reply_open(req, fh->fi);

    } else {

	fuse_reply_err(req, abs(result));

    }

    free_path_pathinfo(&fh->pathinfo);

}
示例#7
0
static void hello_ll_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
{
  if(ino != 2)
    fuse_reply_err(req, EISDIR);
  else if((fi->flags & 3) != O_RDONLY)
    fuse_reply_err(req, EACCES);
  else
    fuse_reply_open(req, fi);
}
示例#8
0
static void do_opendir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
    struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
    struct fuse_file_info fi;

    memset(&fi, 0, sizeof(fi));
    fi.flags = arg->flags;

    if (req->f->op.opendir)
        req->f->op.opendir(req, nodeid, &fi);
    else
        fuse_reply_open(req, &fi);
}
示例#9
0
static void lo_open(fuse_req_t req, fuse_ino_t ino,
			  struct fuse_file_info *fi)
{
	int fd;
	char buf[64];

	sprintf(buf, "/proc/self/fd/%i", lo_fd(req, ino));
	fd = open(buf, fi->flags & ~O_NOFOLLOW);
	if (fd == -1)
		return (void) fuse_reply_err(req, errno);

	fi->fh = fd;
	fuse_reply_open(req, fi);
}
示例#10
0
void hsx_fuse_open (fuse_req_t req, fuse_ino_t ino _U_, struct fuse_file_info *fi)
{
	int err=0;
	uint64_t fh =(uint64_t) malloc (FI_FH_LEN);
	DEBUG_IN ("ino : (%lu)  fi->flags:%d",ino, fi->flags);
	if (!fh){
		err = ENOMEM;
		ERR ("malloc failed:%d\n",err);
		fuse_reply_err(req, err);

	}
	else {
		fi->fh = fh;
		fuse_reply_open(req, fi);
	}
	DEBUG_OUT(" fh:%lu",fh);	
}
/*
 * When the device is created in QEMU it gets initialised here and added to the device linked list.
 */
static void
vhost_net_open(fuse_req_t req, struct fuse_file_info *fi)
{
	struct vhost_device_ctx ctx = fuse_req_to_vhost_ctx(req, fi);
	int err = 0;

	err = ops->new_device(ctx);
	if (err == -1) {
		fuse_reply_err(req, EPERM);
		return;
	}

	fi->fh = err;

	RTE_LOG(INFO, CONFIG, "(%"PRIu64") Device configuration started\n", fi->fh);
	fuse_reply_open(req, fi);
}
示例#12
0
void mfs_meta_opendir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) {
	dirbuf *dirinfo;
	if (ino==META_ROOT_INODE || ino==META_TRASH_INODE || ino==META_UNDEL_INODE || ino==META_RESERVED_INODE) {
		dirinfo = malloc(sizeof(dirbuf));
		pthread_mutex_init(&(dirinfo->lock),NULL);
		dirinfo->p = NULL;
		dirinfo->size = 0;
		dirinfo->wasread = 0;
		fi->fh = (unsigned long)dirinfo;
		if (fuse_reply_open(req,fi) == -ENOENT) {
			fi->fh = 0;
			pthread_mutex_destroy(&(dirinfo->lock));
			free(dirinfo->p);
			free(dirinfo);
		}
	} else {
		fuse_reply_err(req, ENOTDIR);
	}
}
示例#13
0
static void workspace_nfs_opendir(fuse_req_t req, struct workspace_dh_struct *dh)
{
    struct resource_struct *resource=dh->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=dh->pathinfo.path + dh->relpath;
    unsigned int error=0;
    struct directory_struct *directory=dh->directory;
    struct nfsdir *dir=NULL;
    int result=0;

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

    logoutput("workspace_nfs_opendir: path %s", path);

    pthread_mutex_lock(&nfs_export->mutex);

    result=nfs_opendir(nfs_ctx, path, &dir);

    pthread_mutex_unlock(&nfs_export->mutex);

    if (result==0) {

	dh->handle.data = (void *) dir;

        fuse_reply_open(req, dh->fi);
	free_path_pathinfo(&dh->pathinfo);

	return;

    } else {

	error=abs(result);

    }

    logoutput("workspace_opendir, error %i", error);

    fuse_reply_err(req, error);
    free_path_pathinfo(&dh->pathinfo);

}
示例#14
0
文件: ll.c 项目: ksperling/squashfuse
static void sqfs_ll_op_opendir(fuse_req_t req, fuse_ino_t ino,
		struct fuse_file_info *fi) {
	sqfs_ll_i *lli;
	
	fi->fh = (intptr_t)NULL;
	
	lli = malloc(sizeof(*lli));
	if (!lli) {
		fuse_reply_err(req, ENOMEM);
		return;
	}
	
	if (sqfs_ll_iget(req, lli, ino) == SQFS_OK) {
		if (!S_ISDIR(lli->inode.base.mode)) {
			fuse_reply_err(req, ENOTDIR);
		} else {
			fi->fh = (intptr_t)lli;
			fuse_reply_open(req, fi);
			return;
		}
	}
	free(lli);
}
示例#15
0
static void serve_opendir(fuse_req_t req, fuse_ino_t fuse_ino,
                          struct fuse_file_info * fi)
{
	Dprintf("%s(ino = %lu)\n", __FUNCTION__, fuse_ino);
	fdesc_t * fdesc;
	inode_t cfs_ino;
	inode_t parent_cfs_ino;
	int r;

	cfs_ino = fusecfsino(req, fuse_ino);

	r = CALL(reqcfs(req), open, cfs_ino, 0, &fdesc);
	if (r < 0)
	{
		// TODO: fid could be ENOENT, ENOENT, or other
		// TODO: fuse_reply_err(req, ENOTDIR);
		r = fuse_reply_err(req, -r);
		fuse_reply_assert(!r);
		return;
	}

	parent_cfs_ino = (inode_t) hash_map_find_val(reqmount(req)->parents, (void *) cfs_ino);
	if (parent_cfs_ino == INODE_NONE)
	{
		fprintf(stderr, "%s(): no parent ino for ino %u\n", __FUNCTION__, cfs_ino);
		(void) CALL(reqcfs(req), close, fdesc);
		r = fuse_reply_err(req, 1);
		fuse_reply_assert(!r);
		return;
	}
	fdesc->common->parent = parent_cfs_ino;

	fi_set_fdesc(fi, fdesc);

	r = fuse_reply_open(req, fi);
	fuse_reply_assert(!r);
}
示例#16
0
static int zfsfuse_opencreate(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, int fflags, mode_t createmode, const char *name)
{
	if(name && strlen(name) >= MAXNAMELEN)
		return ENAMETOOLONG;

	vfs_t *vfs = (vfs_t *) fuse_req_userdata(req);
	zfsvfs_t *zfsvfs = vfs->vfs_data;

	ZFS_ENTER(zfsvfs);

	cred_t cred;
	zfsfuse_getcred(req, &cred);

	/* Map flags */
	int mode, flags;

	if(fflags & O_WRONLY) {
		mode = VWRITE;
		flags = FWRITE;
	} else if(fflags & O_RDWR) {
		mode = VREAD | VWRITE;
		flags = FREAD | FWRITE;
	} else {
		mode = VREAD;
		flags = FREAD;
	}

	if(fflags & O_CREAT)
		flags |= FCREAT;
	if(fflags & O_SYNC)
		flags |= FSYNC;
	if(fflags & O_DSYNC)
		flags |= FDSYNC;
	if(fflags & O_RSYNC)
		flags |= FRSYNC;
	if(fflags & O_APPEND)
		flags |= FAPPEND;
	if(fflags & O_LARGEFILE)
		flags |= FOFFMAX;
	if(fflags & O_NOFOLLOW)
		flags |= FNOFOLLOW;
	if(fflags & O_TRUNC)
		flags |= FTRUNC;
	if(fflags & O_EXCL)
		flags |= FEXCL;

	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);

	if (flags & FCREAT) {
		enum vcexcl excl;

		/*
		 * Wish to create a file.
		 */
		vattr_t vattr;
		vattr.va_type = VREG;
		vattr.va_mode = createmode;
		vattr.va_mask = AT_TYPE|AT_MODE;
		if (flags & FTRUNC) {
			vattr.va_size = 0;
			vattr.va_mask |= AT_SIZE;
		}
		if (flags & FEXCL)
			excl = EXCL;
		else
			excl = NONEXCL;

		vnode_t *new_vp;
		/* FIXME: check filesystem boundaries */
		error = VOP_CREATE(vp, (char *) name, &vattr, excl, mode, &new_vp, &cred, 0, NULL, NULL);

		if(error)
			goto out;

		VN_RELE(vp);
		vp = new_vp;
	} else {
		/*
		 * Get the attributes to check whether file is large.
		 * We do this only if the O_LARGEFILE flag is not set and
		 * only for regular files.
		 */
		if (!(flags & FOFFMAX) && (vp->v_type == VREG)) {
			vattr_t vattr;
			vattr.va_mask = AT_SIZE;
			if ((error = VOP_GETATTR(vp, &vattr, 0, &cred, NULL)))
				goto out;

			if (vattr.va_size > (u_offset_t) MAXOFF32_T) {
				/*
				 * Large File API - regular open fails
				 * if FOFFMAX flag is set in file mode
				 */
				error = EOVERFLOW;
				goto out;
			}
		}

		/*
		 * Check permissions.
		 */
		if (error = VOP_ACCESS(vp, mode, 0, &cred, NULL))
			goto out;
	}

	if ((flags & FNOFOLLOW) && vp->v_type == VLNK) {
		error = ELOOP;
		goto out;
	}

	vnode_t *old_vp = vp;

	error = VOP_OPEN(&vp, flags, &cred, NULL);

	ASSERT(old_vp == vp);

	if(error)
		goto out;

	struct fuse_entry_param e = { 0 };

	if(flags & FCREAT) {
		error = zfsfuse_stat(vp, &e.attr, &cred);
		if(error)
			goto out;
	}

	file_info_t *info = kmem_cache_alloc(file_info_cache, KM_NOSLEEP);
	if(info == NULL) {
		error = ENOMEM;
		goto out;
	}

	info->vp = vp;
	info->flags = flags;

	fi->fh = (uint64_t) (uintptr_t) info;
	fi->keep_cache = 1;

	if(flags & FCREAT) {
		e.attr_timeout = 0.0;
		e.entry_timeout = 0.0;
		e.ino = VTOZ(vp)->z_id;
		if(e.ino == 3)
			e.ino = 1;
		e.generation = VTOZ(vp)->z_phys->zp_gen;
	}

out:
	if(error) {
		ASSERT(vp->v_count > 0);
		VN_RELE(vp);
	}

	ZFS_EXIT(zfsvfs);

	if(!error) {
		if(!(flags & FCREAT))
			fuse_reply_open(req, fi);
		else
			fuse_reply_create(req, &e, fi);
	}
	return error;
}
示例#17
0
文件: fuse.c 项目: zmike/compiz
static void
compiz_open(fuse_req_t req,
            fuse_ino_t ino,
            struct fuse_file_info *fi)
{
   FuseInode *inode;

   inode = fuseFindInode(inodes, ino, ~0);
   if (!inode)
     {
        fuse_reply_err(req, ENOENT);
        return;
     }

   fi->fh = 0;

   if (inode->type & DIR_MASK)
     {
        fuse_reply_err(req, EISDIR);
     }
   else if (inode->type & WRITE_MASK)
     {
        if ((fi->flags & 3) != O_RDONLY)
          {
             char *data;

             if (fi->flags & O_TRUNC)
               data = strdup("");
             else
               data = fuseGetStringFromInode(inode);

             if (data)
               {
                  FuseWriteBuffer *wb;

                  wb = malloc(sizeof (FuseWriteBuffer));
                  if (wb)
                    {
                       wb->data = data;
                       wb->size = strlen(wb->data);
                       wb->dirty = TRUE;

                       fi->fh = (unsigned long)wb;
                    }
                  else
                    {
                       free(data);
                    }
               }
          }

        fuse_reply_open(req, fi);
     }
   else if ((fi->flags & 3) != O_RDONLY)
     {
        fuse_reply_err(req, EACCES);
     }
   else
     {
        fuse_reply_open(req, fi);
     }
}
示例#18
0
static void cusexmp_open(fuse_req_t req, struct fuse_file_info *fi)
{
        fuse_reply_open(req, fi);
}
示例#19
0
static void overlay_opendir(fuse_req_t req, struct workspace_dh_struct *dh)
{
    struct resource_struct *resource=dh->object->resource;
    struct localfile_struct *localfile=(struct localfile_struct *) resource->data;
    struct pathinfo_struct *pathinfo=&dh->pathinfo;
    unsigned int len0=pathinfo->len - dh->relpath, len1=localfile->pathinfo.len;
    char path[len0 + len1 + 1];
    struct overlay_readdir_struct *overlay_readdir=NULL;
    unsigned int error=0;
    int fd=-1;
    struct directory_struct *directory=dh->directory;
    struct statfs stfs;

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

    if (len0>0) {

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

    }

    path[len1]='\0';

    logoutput("overlayfs_opendir: path %s", path);

    fd=open(path, O_RDONLY | O_DIRECTORY);

    if (fd==-1) {

	error=errno;
	goto error;

    }

    if (fstatfs(fd, &stfs)==-1) {

	error=errno;
	goto error;

    }

    overlay_readdir = malloc(sizeof(struct overlay_readdir_struct));

    if ( ! overlay_readdir ) {

	error=ENOMEM;
	goto error;

    }

    memset(overlay_readdir, 0, sizeof(struct overlay_readdir_struct));

    overlay_readdir->fd=(unsigned int) fd;
    overlay_readdir->data=NULL;
    overlay_readdir->mode=0;

    dh->handle.data = (void *) overlay_readdir;

    /*
	determine the type fileystem
	use a portable generic function here??
    */

    if (stfs.f_bfree==0) {

	/*
	    dealing with a system fs: use readdir
	    and a full or simple synchronize
	*/

	overlay_readdir->data=(void *) init_readdir_readdir(path, fd, &error);

	if (! overlay_readdir->data) {

	    if (error==0) error=EIO;
	    goto error;

	}

	if (directory->synctime.tv_sec==0 && directory->synctime.tv_nsec==0) {

	    overlay_readdir->mode |= _FW_READDIR_MODE_FULL;

	} else {

	    overlay_readdir->mode |= _FW_READDIR_MODE_SIMPLE;

	}

    } else {


	if (directory->synctime.tv_sec==0 && directory->synctime.tv_nsec==0) {

	    /* never synced before, a normal fs: use getdents and full sync*/

	    overlay_readdir->data=(void *) init_readdir_getdents(path, fd, &error);

	    if (! overlay_readdir->data) {

		if (error==0) error=EIO;
		goto error;

	    }

	    overlay_readdir->mode |= _FW_READDIR_MODE_FULL;

	} else {
	    struct stat st;

	    if (fstat(fd, &st)==-1) {

		error=errno;
		goto error;

	    }

	    logoutput("overlayfs_opendir: compare modifytime %li:%li with synctime %li:%li", st.st_mtim.tv_sec, st.st_mtim.tv_nsec, directory->synctime.tv_sec, directory->synctime.tv_nsec);

	    if (st.st_mtim.tv_sec>directory->synctime.tv_sec ||
		(st.st_mtim.tv_sec==directory->synctime.tv_sec && st.st_mtim.tv_nsec>directory->synctime.tv_nsec)) {

		/*
		    directory modification time is changed since last check
		    this means entries are added or removed
		*/

		overlay_readdir->data=(void *) init_readdir_getdents(path, fd, &error);

		if (! overlay_readdir->data) {

		    if (error==0) error=EIO;
		    goto error;

		}

		overlay_readdir->mode |= _FW_READDIR_MODE_SIMPLE;

	    } else {

		overlay_readdir->data=(void *) directory->first;
		overlay_readdir->mode |= _FW_READDIR_MODE_VIRTUAL;

	    }

	}

    }

    fuse_reply_open(req, dh->fi);
    add_pathcache(&dh->pathinfo, dh->parent, dh->object, dh->relpath);
    free_path_pathinfo(&dh->pathinfo);

    return;

    error:

    fuse_reply_err(req, error);

    if (fd>0) {

	close(fd);
	fd=-1;

    }

    if (overlay_readdir) {

	if (overlay_readdir->data && (overlay_readdir->mode & (_FW_READDIR_MODE_SIMPLE | _FW_READDIR_MODE_FULL))) {
	    struct readdir_struct *readdir=(struct readdir_struct *) overlay_readdir->data;

	    if (readdir->close) {

		(* readdir->close) (readdir);

	    } else {

		free(readdir);

	    }

	}

	overlay_readdir->data=NULL;
	free(overlay_readdir);
	overlay_readdir=NULL;

    }

    logoutput("overlayfs_opendir, error %i", error);
    free_path_pathinfo(&dh->pathinfo);

}
示例#20
0
void rozofs_ll_open_nb(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) {
    ientry_t *ie = 0;
    int    ret;        
    void *buffer_p = NULL;
    epgw_mfile_arg_t arg;
    file_t *file = NULL;
    errno = 0;

    /*
    ** Update the IO statistics
    */
    rozofs_thr_cnt_update(rozofs_thr_counter[ROZOFSMOUNT_COUNTER_OTHER], 1);

    int trc_idx = rozofs_trc_req_flags(srv_rozofs_ll_open,ino,NULL,fi->flags);
    /*
    ** allocate a context for saving the fuse parameters
    */
    buffer_p = rozofs_fuse_alloc_saved_context();
    if (buffer_p == NULL)
    {
      severe("out of fuse saved context");
      errno = ENOMEM;
      goto error;
    }
    SAVE_FUSE_PARAM(buffer_p,req);
    SAVE_FUSE_PARAM(buffer_p,ino);
    SAVE_FUSE_PARAM(buffer_p,trc_idx);
    SAVE_FUSE_STRUCT(buffer_p,fi,sizeof( struct fuse_file_info));

    START_PROFILING_NB(buffer_p,rozofs_ll_open);

    DEBUG("open (%lu)\n", (unsigned long int) ino);

    if (!(ie = get_ientry_by_inode(ino))) {
        errno = ENOENT;
        goto error;
    }
    /*
    ** check if it is configured in block mode, in that case we avoid
    ** a transaction with the exportd
    */
    if ((rozofs_mode == 1) ||
       ((ie->timestamp+rozofs_tmr_get_attr_us(rozofs_is_directory_inode(ino))) > rozofs_get_ticker_us()))
    {
      /*
      ** allocate a context for the file descriptor
      */
      file = rozofs_file_working_var_init(ie,ie->fid);
      if (rozofs_cache_mode == 1)
         fi->direct_io = 1;
      else
      {
        if (rozofs_cache_mode == 2)
          fi->keep_cache = 1;
      }
      /*
      ** save the opening flags
      */
      file->open_flags = fi->flags;

      fi->fh = (unsigned long) file;
      /*
      ** update the statistics
      */
      rzkpi_file_stat_update(ie->pfid,(int)0,RZKPI_OPEN);
      /*
      ** Take care of the file caching cache for hybrid SSD/HDD configuration
      */
      rzcachetrack_file(ie->pfid,ie->attrs.attrs.size,ie->attrs.attrs.mtime);
      /*
      ** send back response to fuse
      */
      fuse_reply_open(req, fi);
      goto out; 
    }    
    /*
    ** get the attributes of the file
    */
    arg.arg_gw.eid = exportclt.eid;
    memcpy(arg.arg_gw.fid, ie->fid, sizeof (uuid_t));
    /*
    ** now initiates the transaction towards the remote end
    */

    /*
    ** In case the EXPORT LBG is down and we know this ientry, let's respond to
    ** the requester with the current available information
    */
    if (common_config.client_fast_reconnect) {
      expgw_tx_routing_ctx_t routing_ctx; 
      
      if (expgw_get_export_routing_lbg_info(arg.arg_gw.eid,ie->fid,&routing_ctx) != 0) {
         goto error;
      }
      if (north_lbg_get_state(routing_ctx.lbg_id[0]) != NORTH_LBG_UP) {
	goto short_cut;           
      }      
    } 

#if 1
    ret = rozofs_expgateway_send_routing_common(arg.arg_gw.eid,ie->fid,EXPORT_PROGRAM, EXPORT_VERSION,
                              EP_GETATTR,(xdrproc_t) xdr_epgw_mfile_arg_t,(void *)&arg,
                              rozofs_ll_open_cbk,buffer_p); 
#else
    ret = rozofs_export_send_common(&exportclt,EXPORT_PROGRAM, EXPORT_VERSION,
                              EP_GETATTR,(xdrproc_t) xdr_epgw_mfile_arg_t,(void *)&arg,
                              rozofs_ll_open_cbk,buffer_p); 

#endif
    if (ret < 0) {
      /*
      ** In case of fast reconnect mode let's respond with the previously knows 
      ** parameters instead of failing
      */
      if (common_config.client_fast_reconnect) {
short_cut:
	/*
	** allocate a context for the file descriptor
	*/
	file = rozofs_file_working_var_init(ie,ie->fid);
	if (rozofs_cache_mode == 1)
           fi->direct_io = 1;
	else
	{
          if (rozofs_cache_mode == 2)
            fi->keep_cache = 1;
	}
	/*
	** save the opening flags
	*/
	file->open_flags = fi->flags;
	fi->fh = (unsigned long) file;
	/*
	** update the statistics
	*/
	rzkpi_file_stat_update(ie->pfid,(int)0,RZKPI_OPEN);
	/*
	** Take care of the file caching cache for hybrid SSD/HDD configuration
	*/
	rzcachetrack_file(ie->pfid,ie->attrs.attrs.size,ie->attrs.attrs.mtime);
	/*
	** send back response to fuse
	*/
	fuse_reply_open(req, fi);
	goto out;         
      }
      goto error;  
    }    
    /*
    ** no error just waiting for the answer
    */
    return;
error:
    fuse_reply_err(req, errno);
    /*
    ** release the buffer if has been allocated
    */
out:
    rozofs_trc_rsp_attr(srv_rozofs_ll_open,(fuse_ino_t)file,(ie==NULL)?NULL:ie->attrs.attrs.fid,(errno==0)?0:1,(ie==NULL)?-1:ie->attrs.attrs.size,trc_idx);
    STOP_PROFILING_NB(buffer_p,rozofs_ll_open);
    if (buffer_p != NULL) rozofs_fuse_release_saved_context(buffer_p);

    return;
}
示例#21
0
void rozofs_ll_open_nb(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) {
    ientry_t *ie = 0;
    int    ret;        
    void *buffer_p = NULL;
    epgw_mfile_arg_t arg;
    file_t *file = NULL;
    errno = 0;


    int trc_idx = rozofs_trc_req(srv_rozofs_ll_open,ino,NULL);
    /*
    ** allocate a context for saving the fuse parameters
    */
    buffer_p = rozofs_fuse_alloc_saved_context();
    if (buffer_p == NULL)
    {
      severe("out of fuse saved context");
      errno = ENOMEM;
      goto error;
    }
    SAVE_FUSE_PARAM(buffer_p,req);
    SAVE_FUSE_PARAM(buffer_p,ino);
    SAVE_FUSE_PARAM(buffer_p,trc_idx);
    SAVE_FUSE_STRUCT(buffer_p,fi,sizeof( struct fuse_file_info));

    START_PROFILING_NB(buffer_p,rozofs_ll_open);

    DEBUG("open (%lu)\n", (unsigned long int) ino);

    if (!(ie = get_ientry_by_inode(ino))) {
        errno = ENOENT;
        goto error;
    }
    /*
    ** check if it is configured in block mode, in that case we avoid
    ** a transaction with the exportd
    */
    if ((rozofs_mode == 1) ||
       ((ie->timestamp+rozofs_tmr_get(TMR_FUSE_ATTR_CACHE)*1000000) > rozofs_get_ticker_us()))
    {
      /*
      ** allocate a context for the file descriptor
      */
      file = rozofs_file_working_var_init(ie,ie->fid);
      if (rozofs_cache_mode == 1)
         fi->direct_io = 1;
      else
      {
        if (rozofs_cache_mode == 2)
          fi->keep_cache = 1;
      }
      fi->fh = (unsigned long) file;
      /*
      ** update the statistics
      */
      rzkpi_file_stat_update(ie->pfid,(int)0,RZKPI_OPEN);
      /*
      ** send back response to fuse
      */
      fuse_reply_open(req, fi);
      goto out; 
    }    
    /*
    ** get the attributes of the file
    */
    arg.arg_gw.eid = exportclt.eid;
    memcpy(arg.arg_gw.fid, ie->fid, sizeof (uuid_t));
    /*
    ** now initiates the transaction towards the remote end
    */
#if 1
    ret = rozofs_expgateway_send_routing_common(arg.arg_gw.eid,ie->fid,EXPORT_PROGRAM, EXPORT_VERSION,
                              EP_GETATTR,(xdrproc_t) xdr_epgw_mfile_arg_t,(void *)&arg,
                              rozofs_ll_open_cbk,buffer_p); 
#else
    ret = rozofs_export_send_common(&exportclt,EXPORT_PROGRAM, EXPORT_VERSION,
                              EP_GETATTR,(xdrproc_t) xdr_epgw_mfile_arg_t,(void *)&arg,
                              rozofs_ll_open_cbk,buffer_p); 

#endif
    if (ret < 0) goto error;    
    /*
    ** no error just waiting for the answer
    */
    return;
error:
    fuse_reply_err(req, errno);
    /*
    ** release the buffer if has been allocated
    */
out:
    rozofs_trc_rsp_attr(srv_rozofs_ll_open,(fuse_ino_t)file,(ie==NULL)?NULL:ie->attrs.fid,(errno==0)?0:1,(ie==NULL)?-1:ie->attrs.size,trc_idx);
    STOP_PROFILING_NB(buffer_p,rozofs_ll_open);
    if (buffer_p != NULL) rozofs_fuse_release_saved_context(buffer_p);

    return;
}
示例#22
0
static int zfsfuse_opendir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
{
	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_TRUE);
	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);

	if(vp->v_type != VDIR) {
		error = ENOTDIR;
		goto out;
	}

	cred_t cred;
	zfsfuse_getcred(req, &cred);

	/*
	 * Check permissions.
	 */
	if (error = VOP_ACCESS(vp, VREAD | VEXEC, 0, &cred, NULL))
		goto out;

	vnode_t *old_vp = vp;

	/* XXX: not sure about flags */
	error = VOP_OPEN(&vp, FREAD, &cred, NULL);

	ASSERT(old_vp == vp);

	if(!error) {
		file_info_t *info = kmem_cache_alloc(file_info_cache, KM_NOSLEEP);
		if(info == NULL) {
			error = ENOMEM;
			goto out;
		}

		info->vp = vp;
		info->flags = FREAD;

		fi->fh = (uint64_t) (uintptr_t) info;
	}

out:
	if(error)
		VN_RELE(vp);
	ZFS_EXIT(zfsvfs);

	if(!error)
		fuse_reply_open(req, fi);

	return error;
}