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); } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); } }
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); }
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); }
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); }
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; }
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); } }
static void cusexmp_open(fuse_req_t req, struct fuse_file_info *fi) { fuse_reply_open(req, fi); }
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); }
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; }
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; }
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; }