int _9p_symlink( _9p_request_data_t * preq9p, void * pworker_data, u32 * plenout, char * preply) { char * cursor = preq9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE ; nfs_worker_data_t * pwkrdata = (nfs_worker_data_t *)pworker_data ; u16 * msgtag = NULL ; u32 * fid = NULL ; u16 * name_len = NULL ; char * name_str = NULL ; u16 * linkcontent_len = NULL ; char * linkcontent_str = NULL ; u32 * gid = NULL ; _9p_fid_t * pfid = NULL ; _9p_qid_t qid_symlink ; cache_entry_t * pentry_symlink = NULL ; fsal_name_t symlink_name ; fsal_attrib_list_t fsalattr ; cache_inode_status_t cache_status ; fsal_accessmode_t mode = 0777; cache_inode_create_arg_t create_arg; int rc = 0 ; int err = 0 ; if ( !preq9p || !pworker_data || !plenout || !preply ) return -1 ; memset(&create_arg, 0, sizeof(create_arg)); /* Get data */ _9p_getptr( cursor, msgtag, u16 ) ; _9p_getptr( cursor, fid, u32 ) ; _9p_getstr( cursor, name_len, name_str ) ; _9p_getstr( cursor, linkcontent_len, linkcontent_str ) ; _9p_getptr( cursor, gid, u32 ) ; LogDebug( COMPONENT_9P, "TSYMLINK: tag=%u fid=%u name=%.*s linkcontent=%.*s gid=%u", (u32)*msgtag, *fid, *name_len, name_str, *linkcontent_len, linkcontent_str, *gid ) ; if( *fid >= _9P_FID_PER_CONN ) { err = ERANGE ; rc = _9p_rerror( preq9p, msgtag, &err, plenout, preply ) ; return rc ; } pfid = &preq9p->pconn->fids[*fid] ; snprintf( symlink_name.name, FSAL_MAX_NAME_LEN, "%.*s", *name_len, name_str ) ; snprintf( create_arg.link_content.path, FSAL_MAX_PATH_LEN, "%.*s", *linkcontent_len, linkcontent_str ) ; /* Let's do the job */ /* BUGAZOMEU: @todo : the gid parameter is not used yet, flags is not yet used */ if( ( pentry_symlink = cache_inode_create( pfid->pentry, &symlink_name, SYMBOLIC_LINK, pfid->pexport->cache_inode_policy, mode, &create_arg, &fsalattr, pwkrdata->ht, &pwkrdata->cache_inode_client, &pfid->fsal_op_context, &cache_status)) == NULL) { err = _9p_tools_errno( cache_status ) ; ; rc = _9p_rerror( preq9p, msgtag, &err, plenout, preply ) ; return rc ; } /* Build the qid */ qid_symlink.type = _9P_QTSYMLINK ; qid_symlink.version = 0 ; qid_symlink.path = fsalattr.fileid ; /* Build the reply */ _9p_setinitptr( cursor, preply, _9P_RSYMLINK ) ; _9p_setptr( cursor, msgtag, u16 ) ; _9p_setqid( cursor, qid_symlink ) ; _9p_setendptr( cursor, preply ) ; _9p_checkbound( cursor, preply, plenout ) ; LogDebug( COMPONENT_9P, "RSYMLINK: tag=%u fid=%u name=%.*s qid=(type=%u,version=%u,path=%llu)", (u32)*msgtag, *fid, *name_len, name_str, qid_symlink.type, qid_symlink.version, (unsigned long long)qid_symlink.path ) ; return 1 ; }
int _9p_mknod( _9p_request_data_t * preq9p, void * pworker_data, u32 * plenout, char * preply) { char * cursor = preq9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE ; nfs_worker_data_t * pwkrdata = (nfs_worker_data_t *)pworker_data ; u16 * msgtag = NULL ; u32 * fid = NULL ; u32 * mode = NULL ; u32 * gid = NULL ; u32 * major = NULL ; u32 * minor = NULL ; u16 * name_len = NULL ; char * name_str = NULL ; _9p_fid_t * pfid = NULL ; _9p_qid_t qid_newobj ; cache_entry_t * pentry_newobj = NULL ; fsal_name_t obj_name ; fsal_attrib_list_t fsalattr ; cache_inode_status_t cache_status ; cache_inode_file_type_t nodetype; cache_inode_create_arg_t create_arg; int rc = 0 ; int err = 0 ; if ( !preq9p || !pworker_data || !plenout || !preply ) return -1 ; memset(&create_arg, 0, sizeof(create_arg)); /* Get data */ _9p_getptr( cursor, msgtag, u16 ) ; _9p_getptr( cursor, fid, u32 ) ; _9p_getstr( cursor, name_len, name_str ) ; _9p_getptr( cursor, mode, u32 ) ; _9p_getptr( cursor, major, u32 ) ; _9p_getptr( cursor, minor, u32 ) ; _9p_getptr( cursor, gid, u32 ) ; LogDebug( COMPONENT_9P, "TMKNOD: tag=%u fid=%u name=%.*s mode=0%o major=%u minor=%u gid=%u", (u32)*msgtag, *fid, *name_len, name_str, *mode, *major, *minor, *gid ) ; if( *fid >= _9P_FID_PER_CONN ) { err = ERANGE ; rc = _9p_rerror( preq9p, msgtag, &err, plenout, preply ) ; return rc ; } pfid = &preq9p->pconn->fids[*fid] ; snprintf( obj_name.name, FSAL_MAX_NAME_LEN, "%.*s", *name_len, name_str ) ; /* Check for bad type */ if( !( *mode & (S_IFCHR|S_IFBLK|S_IFIFO|S_IFSOCK) ) ) { err = ERANGE ; rc = _9p_rerror( preq9p, msgtag, &err, plenout, preply ) ; return rc ; } /* Set the nodetype */ if( *mode & S_IFCHR ) nodetype = CHARACTER_FILE ; if( *mode & S_IFBLK ) nodetype = BLOCK_FILE ; if( *mode & S_IFIFO ) nodetype = FIFO_FILE ; if( *mode & S_IFSOCK ) nodetype = SOCKET_FILE ; create_arg.dev_spec.major = *major ; create_arg.dev_spec.minor = *minor ; /* Create the directory */ /** @todo BUGAZOMEU the gid parameter is not used yet */ if( ( pentry_newobj = cache_inode_create( pfid->pentry, &obj_name, nodetype, pfid->pexport->cache_inode_policy, *mode, &create_arg, &fsalattr, pwkrdata->ht, &pwkrdata->cache_inode_client, &pfid->fsal_op_context, &cache_status)) == NULL) { err = _9p_tools_errno( cache_status ) ; ; rc = _9p_rerror( preq9p, msgtag, &err, plenout, preply ) ; return rc ; } /* Build the qid */ qid_newobj.type = _9P_QTTMP ; /** @todo BUGAZOMEU For wanting of something better */ qid_newobj.version = 0 ; qid_newobj.path = fsalattr.fileid ; /* Build the reply */ _9p_setinitptr( cursor, preply, _9P_RMKNOD ) ; _9p_setptr( cursor, msgtag, u16 ) ; _9p_setqid( cursor, qid_newobj ) ; _9p_setendptr( cursor, preply ) ; _9p_checkbound( cursor, preply, plenout ) ; LogDebug( COMPONENT_9P, "TMKNOD: tag=%u fid=%u name=%.*s major=%u minor=%u qid=(type=%u,version=%u,path=%llu)", (u32)*msgtag, *fid, *name_len, name_str, *major, *minor, qid_newobj.type, qid_newobj.version, (unsigned long long)qid_newobj.path ) ; return 1 ; }
int _9p_lopen( _9p_request_data_t * preq9p, void * pworker_data, u32 * plenout, char * preply) { char * cursor = preq9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE ; u16 * msgtag = NULL ; u32 * fid = NULL ; u32 * flags = NULL ; cache_inode_status_t cache_status ; fsal_openflags_t openflags = 0 ; if( !preq9p || !pworker_data || !plenout || !preply ) return -1 ; _9p_fid_t * pfid = NULL ; /* Get data */ _9p_getptr( cursor, msgtag, u16 ) ; _9p_getptr( cursor, fid, u32 ) ; _9p_getptr( cursor, flags, u32 ) ; LogDebug( COMPONENT_9P, "TLOPEN: tag=%u fid=%u flags=0x%x", (u32)*msgtag, *fid, *flags ) ; if( *fid >= _9P_FID_PER_CONN ) return _9p_rerror( preq9p, msgtag, ERANGE, plenout, preply ) ; pfid = &preq9p->pconn->fids[*fid] ; _9p_openflags2FSAL( flags, &openflags ) ; if( pfid->pentry->type == REGULAR_FILE ) /** @todo: Maybe other types (FIFO, sOCKET,...) may require to be opened too */ { if(cache_inode_open( pfid->pentry, openflags, &pfid->fsal_op_context, 0, &cache_status) != CACHE_INODE_SUCCESS) return _9p_rerror( preq9p, msgtag, _9p_tools_errno( cache_status ), plenout, preply ) ; } /* iounit = 0 by default */ pfid->specdata.iounit = 0 ; /* Build the reply */ _9p_setinitptr( cursor, preply, _9P_RLOPEN ) ; _9p_setptr( cursor, msgtag, u16 ) ; _9p_setqid( cursor, pfid->qid ) ; _9p_setptr( cursor, &pfid->specdata.iounit, u32 ) ; _9p_setendptr( cursor, preply ) ; _9p_checkbound( cursor, preply, plenout ) ; LogDebug( COMPONENT_9P, "RLOPEN: tag=%u fid=%u qid=(type=%u,version=%u,path=%llu) iounit=%u", *msgtag, *fid, (u32)pfid->qid.type, pfid->qid.version, (unsigned long long)pfid->qid.path, pfid->specdata.iounit ) ; return 1 ; }
int _9p_lcreate(struct _9p_request_data *req9p, u32 *plenout, char *preply) { char *cursor = req9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE; u16 *msgtag = NULL; u32 *fid = NULL; u32 *flags = NULL; u32 *mode = NULL; u32 *gid = NULL; u16 *name_len = NULL; char *name_str = NULL; struct _9p_fid *pfid = NULL; struct _9p_qid qid_newfile; u32 iounit = _9P_IOUNIT; struct fsal_obj_handle *pentry_newfile = NULL; char file_name[MAXNAMLEN+1]; fsal_status_t fsal_status; fsal_openflags_t openflags = 0; struct attrlist sattr; fsal_verifier_t verifier; enum fsal_create_mode createmode = FSAL_UNCHECKED; /* Get data */ _9p_getptr(cursor, msgtag, u16); _9p_getptr(cursor, fid, u32); _9p_getstr(cursor, name_len, name_str); _9p_getptr(cursor, flags, u32); _9p_getptr(cursor, mode, u32); _9p_getptr(cursor, gid, u32); LogDebug(COMPONENT_9P, "TLCREATE: tag=%u fid=%u name=%.*s flags=0%o mode=0%o gid=%u", (u32) *msgtag, *fid, *name_len, name_str, *flags, *mode, *gid); if (*fid >= _9P_FID_PER_CONN) return _9p_rerror(req9p, msgtag, ERANGE, plenout, preply); pfid = req9p->pconn->fids[*fid]; /* Check that it is a valid fid */ if (pfid == NULL || pfid->pentry == NULL) { LogDebug(COMPONENT_9P, "request on invalid fid=%u", *fid); return _9p_rerror(req9p, msgtag, EIO, plenout, preply); } _9p_init_opctx(pfid, req9p); if ((op_ctx->export_perms->options & EXPORT_OPTION_WRITE_ACCESS) == 0) return _9p_rerror(req9p, msgtag, EROFS, plenout, preply); if (*name_len >= sizeof(file_name)) { LogDebug(COMPONENT_9P, "request with name too long (%u)", *name_len); return _9p_rerror(req9p, msgtag, ENAMETOOLONG, plenout, preply); } snprintf(file_name, sizeof(file_name), "%.*s", *name_len, name_str); _9p_openflags2FSAL(flags, &openflags); pfid->state->state_data.fid.share_access = _9p_openflags_to_share_access(flags); memset(&verifier, 0, sizeof(verifier)); memset(&sattr, 0, sizeof(sattr)); sattr.valid_mask = ATTR_MODE | ATTR_GROUP; sattr.mode = *mode; sattr.group = *gid; if (*flags & 0x10) { /* Filesize is already 0. */ sattr.valid_mask |= ATTR_SIZE; } if (*flags & 0x1000) { /* If OEXCL, use FSAL_EXCLUSIVE_9P create mode * so that we can pass the attributes specified * above. Verifier is ignored for this create mode * because we don't have to deal with retry. */ createmode = FSAL_EXCLUSIVE_9P; } fsal_status = fsal_open2(pfid->pentry, pfid->state, openflags, createmode, file_name, &sattr, verifier, &pentry_newfile, NULL); /* Release the attributes (may release an inherited ACL) */ fsal_release_attrs(&sattr); if (FSAL_IS_ERROR(fsal_status)) return _9p_rerror(req9p, msgtag, _9p_tools_errno(fsal_status), plenout, preply); /* put parent directory entry */ pfid->pentry->obj_ops->put_ref(pfid->pentry); /* Build the qid */ qid_newfile.type = _9P_QTFILE; qid_newfile.version = 0; qid_newfile.path = pentry_newfile->fileid; /* The fid will represent the new file now - we can't fail anymore */ pfid->pentry = pentry_newfile; pfid->qid = qid_newfile; pfid->xattr = NULL; pfid->opens = 1; /* Build the reply */ _9p_setinitptr(cursor, preply, _9P_RLCREATE); _9p_setptr(cursor, msgtag, u16); _9p_setqid(cursor, qid_newfile); _9p_setvalue(cursor, iounit, u32); _9p_setendptr(cursor, preply); _9p_checkbound(cursor, preply, plenout); LogDebug(COMPONENT_9P, "RLCREATE: tag=%u fid=%u name=%.*s qid=(type=%u,version=%u,path=%llu) iounit=%u pentry=%p", (u32) *msgtag, *fid, *name_len, name_str, qid_newfile.type, qid_newfile.version, (unsigned long long)qid_newfile.path, iounit, pfid->pentry); return 1; }
int _9p_lopen(struct _9p_request_data *req9p, void *worker_data, u32 *plenout, char *preply) { char *cursor = req9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE; u16 *msgtag = NULL; u32 *fid = NULL; u32 *flags = NULL; cache_inode_status_t cache_status; fsal_openflags_t openflags = 0; struct _9p_fid *pfid = NULL; /* Get data */ _9p_getptr(cursor, msgtag, u16); _9p_getptr(cursor, fid, u32); _9p_getptr(cursor, flags, u32); LogDebug(COMPONENT_9P, "TLOPEN: tag=%u fid=%u flags=0x%x", (u32) *msgtag, *fid, *flags); if (*fid >= _9P_FID_PER_CONN) return _9p_rerror(req9p, worker_data, msgtag, ERANGE, plenout, preply); pfid = req9p->pconn->fids[*fid]; /* Check that it is a valid fid */ if (pfid == NULL || pfid->pentry == NULL) { LogDebug(COMPONENT_9P, "request on invalid fid=%u", *fid); return _9p_rerror(req9p, worker_data, msgtag, EIO, plenout, preply); } _9p_openflags2FSAL(flags, &openflags); op_ctx = &pfid->op_context; if (pfid->pentry->type == REGULAR_FILE) { /** @todo: Maybe other types (FIFO, SOCKET,...) require * to be opened too */ if (!atomic_postinc_uint32_t(&pfid->opens)) { cache_status = cache_inode_inc_pin_ref(pfid->pentry); if (cache_status != CACHE_INODE_SUCCESS) return _9p_rerror(req9p, worker_data, msgtag, _9p_tools_errno(cache_status), plenout, preply); } cache_status = cache_inode_open(pfid->pentry, openflags, 0); if (cache_status != CACHE_INODE_SUCCESS) return _9p_rerror(req9p, worker_data, msgtag, _9p_tools_errno(cache_status), plenout, preply); } /* iounit = 0 by default */ pfid->specdata.iounit = _9P_IOUNIT; /* Build the reply */ _9p_setinitptr(cursor, preply, _9P_RLOPEN); _9p_setptr(cursor, msgtag, u16); _9p_setqid(cursor, pfid->qid); _9p_setptr(cursor, &pfid->specdata.iounit, u32); _9p_setendptr(cursor, preply); _9p_checkbound(cursor, preply, plenout); LogDebug(COMPONENT_9P, "RLOPEN: tag=%u fid=%u qid=(type=%u,version=%u,path=%llu) iounit=%u", *msgtag, *fid, (u32) pfid->qid.type, pfid->qid.version, (unsigned long long)pfid->qid.path, pfid->specdata.iounit); return 1; }
int _9p_symlink(struct _9p_request_data *req9p, void *worker_data, u32 *plenout, char *preply) { char *cursor = req9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE; u16 *msgtag = NULL; u32 *fid = NULL; u16 *name_len = NULL; char *name_str = NULL; u16 *linkcontent_len = NULL; char *linkcontent_str = NULL; u32 *gid = NULL; struct _9p_fid *pfid = NULL; struct _9p_qid qid_symlink; cache_entry_t *pentry_symlink = NULL; char symlink_name[MAXNAMLEN]; uint64_t fileid; cache_inode_status_t cache_status; uint32_t mode = 0777; cache_inode_create_arg_t create_arg; memset(&create_arg, 0, sizeof(create_arg)); /* Get data */ _9p_getptr(cursor, msgtag, u16); _9p_getptr(cursor, fid, u32); _9p_getstr(cursor, name_len, name_str); _9p_getstr(cursor, linkcontent_len, linkcontent_str); _9p_getptr(cursor, gid, u32); LogDebug(COMPONENT_9P, "TSYMLINK: tag=%u fid=%u name=%.*s linkcontent=%.*s gid=%u", (u32) *msgtag, *fid, *name_len, name_str, *linkcontent_len, linkcontent_str, *gid); if (*fid >= _9P_FID_PER_CONN) return _9p_rerror(req9p, worker_data, msgtag, ERANGE, plenout, preply); pfid = req9p->pconn->fids[*fid]; /* Check that it is a valid fid */ if (pfid == NULL || pfid->pentry == NULL) { LogDebug(COMPONENT_9P, "request on invalid fid=%u", *fid); return _9p_rerror(req9p, worker_data, msgtag, EIO, plenout, preply); } if ((pfid->op_context.export_perms->options & EXPORT_OPTION_WRITE_ACCESS) == 0) return _9p_rerror(req9p, worker_data, msgtag, EROFS, plenout, preply); op_ctx = &pfid->op_context; snprintf(symlink_name, MAXNAMLEN, "%.*s", *name_len, name_str); create_arg.link_content = gsh_malloc(MAXPATHLEN); if (create_arg.link_content == NULL) return _9p_rerror(req9p, worker_data, msgtag, EFAULT, plenout, preply); snprintf(create_arg.link_content, MAXPATHLEN, "%.*s", *linkcontent_len, linkcontent_str); /* Let's do the job */ /* BUGAZOMEU: @todo : the gid parameter is not used yet, * flags is not yet used */ cache_status = cache_inode_create(pfid->pentry, symlink_name, SYMBOLIC_LINK, mode, &create_arg, &pentry_symlink); if (create_arg.link_content != NULL) gsh_free(create_arg.link_content); if (pentry_symlink == NULL) { return _9p_rerror(req9p, worker_data, msgtag, _9p_tools_errno(cache_status), plenout, preply); } /* This is not a TATTACH fid */ pfid->from_attach = false; cache_status = cache_inode_fileid(pentry_symlink, &fileid); /* put the entry: * we don't want to remember it even if cache_inode_fileid fails. */ cache_inode_put(pentry_symlink); if (cache_status != CACHE_INODE_SUCCESS) { return _9p_rerror(req9p, worker_data, msgtag, _9p_tools_errno(cache_status), plenout, preply); } /* Build the qid */ qid_symlink.type = _9P_QTSYMLINK; qid_symlink.version = 0; qid_symlink.path = fileid; /* Build the reply */ _9p_setinitptr(cursor, preply, _9P_RSYMLINK); _9p_setptr(cursor, msgtag, u16); _9p_setqid(cursor, qid_symlink); _9p_setendptr(cursor, preply); _9p_checkbound(cursor, preply, plenout); LogDebug(COMPONENT_9P, "RSYMLINK: tag=%u fid=%u name=%.*s qid=(type=%u,version=%u,path=%llu)", (u32) *msgtag, *fid, *name_len, name_str, qid_symlink.type, qid_symlink.version, (unsigned long long)qid_symlink.path); return 1; }
int _9p_auth( _9p_request_data_t * preq9p, void * pworker_data, u32 * plenout, char * preply) { char * cursor = preq9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE ; nfs_worker_data_t * pwkrdata = (nfs_worker_data_t *)pworker_data ; u16 * msgtag = NULL ; u32 * afid = NULL ; u16 * uname_len = NULL ; char * uname_str = NULL ; u16 * aname_len = NULL ; char * aname_str = NULL ; u32 * n_aname = NULL ; fsal_attrib_list_t fsalattr ; u32 err = 0 ; _9p_fid_t * pfid = NULL ; exportlist_t * pexport = NULL; unsigned int found = FALSE; cache_inode_status_t cache_status ; cache_inode_fsal_data_t fsdata ; if ( !preq9p || !pworker_data || !plenout || !preply ) return -1 ; /* Get data */ _9p_getptr( cursor, msgtag, u16 ) ; _9p_getptr( cursor, afid, u32 ) ; _9p_getstr( cursor, uname_len, uname_str ) ; _9p_getstr( cursor, aname_len, aname_str ) ; _9p_getptr( cursor, n_aname, u32 ) ; LogDebug( COMPONENT_9P, "TAUTH: tag=%u afid=%d uname='%.*s' aname='%.*s' n_uname=%d", (u32)*msgtag, *afid, (int)*uname_len, uname_str, (int)*aname_len, aname_str, *n_aname ) ; /* * Find the export for the aname (using as well Path or Tag ) */ for( pexport = nfs_param.pexportlist; pexport != NULL; pexport = pexport->next) { if(aname_str[0] != '/') { /* The input value may be a "Tag" */ if(!strncmp(aname_str, pexport->FS_tag, strlen( pexport->FS_tag ) ) ) { found = TRUE ; break; } } else { if(!strncmp(aname_str, pexport->fullpath, strlen( pexport->fullpath ) ) ) { found = TRUE ; break; } } } /* for */ /* Did we find something ? */ if( found == FALSE ) return _9p_rerror( preq9p, msgtag, ENOENT, plenout, preply ) ; if( *afid >= _9P_FID_PER_CONN ) return _9p_rerror( preq9p, msgtag, ERANGE, plenout, preply ) ; /* Set pexport and fid id in fid */ pfid= &preq9p->pconn->fids[*afid] ; pfid->pexport = pexport ; pfid->fid = *afid ; memcpy( &pfid->fsal_op_context, &pwkrdata->thread_fsal_context, sizeof( fsal_op_context_t ) ) ; /* Is user name provided as a string or as an uid ? */ if( *uname_len != 0 ) { /* Build the fid creds */ if( ( err = _9p_tools_get_fsal_op_context_by_name( *uname_len, uname_str, pfid ) ) != 0 ) return _9p_rerror( preq9p, msgtag, -err, plenout, preply ) ; } else { /* Build the fid creds */ if( ( err = _9p_tools_get_fsal_op_context_by_uid( *n_aname, pfid ) ) != 0 ) return _9p_rerror( preq9p, msgtag, -err, plenout, preply ) ; } /* Get the related pentry */ fsdata.fh_desc.start = (char *)pexport->proot_handle ; fsdata.fh_desc.len = sizeof( fsal_handle_t ) ; pfid->pentry = cache_inode_get( &fsdata, &fsalattr, &pfid->fsal_op_context, NULL, &cache_status ) ; if( pfid->pentry == NULL ) return _9p_rerror( preq9p, msgtag, _9p_tools_errno( cache_status ), plenout, preply ) ; /* Compute the qid */ pfid->qid.type = _9P_QTDIR ; pfid->qid.version = 0 ; /* No cache, we want the client to stay synchronous with the server */ pfid->qid.path = fsalattr.fileid ; /* Build the reply */ _9p_setinitptr( cursor, preply, _9P_RATTACH ) ; _9p_setptr( cursor, msgtag, u16 ) ; _9p_setqid( cursor, pfid->qid ) ; _9p_setendptr( cursor, preply ) ; _9p_checkbound( cursor, preply, plenout ) ; LogDebug( COMPONENT_9P, "RAUTH: tag=%u afid=%u qid=(type=%u,version=%u,path=%llu)", *msgtag, *afid, (u32)pfid->qid.type, pfid->qid.version, (unsigned long long)pfid->qid.path ) ; return 1 ; }
int _9p_walk(struct _9p_request_data *req9p, void *worker_data, u32 *plenout, char *preply) { char *cursor = req9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE; unsigned int i = 0; u16 *msgtag = NULL; u32 *fid = NULL; u32 *newfid = NULL; u16 *nwname = NULL; u16 *wnames_len; char *wnames_str; uint64_t fileid; cache_inode_status_t cache_status; cache_entry_t *pentry = NULL; char name[MAXNAMLEN]; u16 *nwqid; struct _9p_fid *pfid = NULL; struct _9p_fid *pnewfid = NULL; /* Now Get data */ _9p_getptr(cursor, msgtag, u16); _9p_getptr(cursor, fid, u32); _9p_getptr(cursor, newfid, u32); _9p_getptr(cursor, nwname, u16); LogDebug(COMPONENT_9P, "TWALK: tag=%u fid=%u newfid=%u nwname=%u", (u32) *msgtag, *fid, *newfid, *nwname); if (*fid >= _9P_FID_PER_CONN) return _9p_rerror(req9p, worker_data, msgtag, ERANGE, plenout, preply); if (*newfid >= _9P_FID_PER_CONN) return _9p_rerror(req9p, worker_data, msgtag, ERANGE, plenout, preply); pfid = req9p->pconn->fids[*fid]; /* Check that it is a valid fid */ if (pfid == NULL || pfid->pentry == NULL) { LogDebug(COMPONENT_9P, "request on invalid fid=%u", *fid); return _9p_rerror(req9p, worker_data, msgtag, EIO, plenout, preply); } op_ctx = &pfid->op_context; pnewfid = gsh_calloc(1, sizeof(struct _9p_fid)); if (pnewfid == NULL) return _9p_rerror(req9p, worker_data, msgtag, ERANGE, plenout, preply); /* Is this a lookup or a fid cloning operation ? */ if (*nwname == 0) { /* Cloning operation */ memcpy((char *)pnewfid, (char *)pfid, sizeof(struct _9p_fid)); /* Set the new fid id */ pnewfid->fid = *newfid; /* This is not a TATTACH fid */ pnewfid->from_attach = false; /* Increments refcount */ (void) cache_inode_lru_ref(pnewfid->pentry, LRU_REQ_STALE_OK); } else { /* the walk is in fact a lookup */ pentry = pfid->pentry; for (i = 0; i < *nwname; i++) { _9p_getstr(cursor, wnames_len, wnames_str); snprintf(name, MAXNAMLEN, "%.*s", *wnames_len, wnames_str); LogDebug(COMPONENT_9P, "TWALK (lookup): tag=%u fid=%u newfid=%u (component %u/%u :%s)", (u32) *msgtag, *fid, *newfid, i + 1, *nwname, name); if (pnewfid->pentry == pentry) pnewfid->pentry = NULL; /* refcount +1 */ cache_status = cache_inode_lookup(pentry, name, &pnewfid->pentry); if (pnewfid->pentry == NULL) { gsh_free(pnewfid); return _9p_rerror(req9p, worker_data, msgtag, _9p_tools_errno(cache_status), plenout, preply); } if (pentry != pfid->pentry) cache_inode_put(pentry); pentry = pnewfid->pentry; } pnewfid->fid = *newfid; pnewfid->op_context = pfid->op_context; pnewfid->ppentry = pfid->pentry; strncpy(pnewfid->name, name, MAXNAMLEN-1); /* gdata ref is not hold : the pfid, which use same gdata */ /* will be clunked after pnewfid */ /* This clunk release the gdata */ pnewfid->gdata = pfid->gdata; /* This is not a TATTACH fid */ pnewfid->from_attach = false; cache_status = cache_inode_fileid(pnewfid->pentry, &fileid); if (cache_status != CACHE_INODE_SUCCESS) { gsh_free(pnewfid); return _9p_rerror(req9p, worker_data, msgtag, _9p_tools_errno(cache_status), plenout, preply); } /* Build the qid */ /* No cache, we want the client to stay synchronous * with the server */ pnewfid->qid.version = 0; pnewfid->qid.path = fileid; pnewfid->specdata.xattr.xattr_id = 0; pnewfid->specdata.xattr.xattr_content = NULL; switch (pnewfid->pentry->type) { case REGULAR_FILE: case CHARACTER_FILE: case BLOCK_FILE: case SOCKET_FILE: case FIFO_FILE: pnewfid->qid.type = _9P_QTFILE; break; case SYMBOLIC_LINK: pnewfid->qid.type = _9P_QTSYMLINK; break; case DIRECTORY: pnewfid->qid.type = _9P_QTDIR; break; default: LogMajor(COMPONENT_9P, "implementation error, you should not see this message !!!!!!"); gsh_free(pnewfid); return _9p_rerror(req9p, worker_data, msgtag, EINVAL, plenout, preply); break; } } /* keep info on new fid */ req9p->pconn->fids[*newfid] = pnewfid; /* As much qid as requested fid */ nwqid = nwname; /* Hold refcount on gdata */ uid2grp_hold_group_data(pnewfid->gdata); /* Build the reply */ _9p_setinitptr(cursor, preply, _9P_RWALK); _9p_setptr(cursor, msgtag, u16); _9p_setptr(cursor, nwqid, u16); for (i = 0; i < *nwqid; i++) { /** @todo: should be different qids * for each directory walked through */ _9p_setqid(cursor, pnewfid->qid); } _9p_setendptr(cursor, preply); _9p_checkbound(cursor, preply, plenout); LogDebug(COMPONENT_9P, "RWALK: tag=%u fid=%u newfid=%u nwqid=%u fileid=%llu pentry=%p refcount=%i", (u32) *msgtag, *fid, *newfid, *nwqid, (unsigned long long)pnewfid->qid.path, pnewfid->pentry, pnewfid->pentry->lru.refcnt); return 1; }
int _9p_mkdir(struct _9p_request_data *req9p, u32 *plenout, char *preply) { char *cursor = req9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE; u16 *msgtag = NULL; u32 *fid = NULL; u32 *mode = NULL; u32 *gid = NULL; u16 *name_len = NULL; char *name_str = NULL; struct _9p_fid *pfid = NULL; struct _9p_qid qid_newdir; struct fsal_obj_handle *pentry_newdir = NULL; char dir_name[MAXNAMLEN+1]; fsal_status_t fsal_status; struct attrlist sattr; /* Get data */ _9p_getptr(cursor, msgtag, u16); _9p_getptr(cursor, fid, u32); _9p_getstr(cursor, name_len, name_str); _9p_getptr(cursor, mode, u32); _9p_getptr(cursor, gid, u32); LogDebug(COMPONENT_9P, "TMKDIR: tag=%u fid=%u name=%.*s mode=0%o gid=%u", (u32) *msgtag, *fid, *name_len, name_str, *mode, *gid); if (*fid >= _9P_FID_PER_CONN) return _9p_rerror(req9p, msgtag, ERANGE, plenout, preply); pfid = req9p->pconn->fids[*fid]; /* Check that it is a valid fid */ if (pfid == NULL || pfid->pentry == NULL) { LogDebug(COMPONENT_9P, "request on invalid fid=%u", *fid); return _9p_rerror(req9p, msgtag, EIO, plenout, preply); } _9p_init_opctx(pfid, req9p); if ((op_ctx->export_perms->options & EXPORT_OPTION_WRITE_ACCESS) == 0) return _9p_rerror(req9p, msgtag, EROFS, plenout, preply); if (*name_len >= sizeof(dir_name)) { LogDebug(COMPONENT_9P, "request with name too long (%u)", *name_len); return _9p_rerror(req9p, msgtag, ENAMETOOLONG, plenout, preply); } snprintf(dir_name, sizeof(dir_name), "%.*s", *name_len, name_str); fsal_prepare_attrs(&sattr, ATTR_MODE); sattr.mode = *mode; sattr.valid_mask = ATTR_MODE; /* Create the directory */ /* BUGAZOMEU: @todo : the gid parameter is not used yet */ fsal_status = fsal_create(pfid->pentry, dir_name, DIRECTORY, &sattr, NULL, &pentry_newdir, NULL); /* Release the attributes (may release an inherited ACL) */ fsal_release_attrs(&sattr); if (FSAL_IS_ERROR(fsal_status)) return _9p_rerror(req9p, msgtag, _9p_tools_errno(fsal_status), plenout, preply); pentry_newdir->obj_ops.put_ref(pentry_newdir); /* Build the qid */ qid_newdir.type = _9P_QTDIR; qid_newdir.version = 0; qid_newdir.path = pentry_newdir->fileid; /* Build the reply */ _9p_setinitptr(cursor, preply, _9P_RMKDIR); _9p_setptr(cursor, msgtag, u16); _9p_setqid(cursor, qid_newdir); _9p_setendptr(cursor, preply); _9p_checkbound(cursor, preply, plenout); LogDebug(COMPONENT_9P, "RMKDIR: tag=%u fid=%u name=%.*s qid=(type=%u,version=%u,path=%llu)", (u32) *msgtag, *fid, *name_len, name_str, qid_newdir.type, qid_newdir.version, (unsigned long long)qid_newdir.path); return 1; }
int _9p_lopen( _9p_request_data_t * preq9p, void * pworker_data, u32 * plenout, char * preply) { char * cursor = preq9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE ; int rc = 0 ; u32 err = 0 ; nfs_worker_data_t * pwkrdata = (nfs_worker_data_t *)pworker_data ; u16 * msgtag = NULL ; u32 * fid = NULL ; u32 * mode = NULL ; fsal_accessflags_t fsalaccess ; cache_inode_status_t cache_status ; if ( !preq9p || !pworker_data || !plenout || !preply ) return -1 ; _9p_fid_t * pfid = NULL ; /* Get data */ _9p_getptr( cursor, msgtag, u16 ) ; _9p_getptr( cursor, fid, u32 ) ; _9p_getptr( cursor, mode, u32 ) ; LogDebug( COMPONENT_9P, "TLOPEN: tag=%u fid=%u mode=0x%x", (u32)*msgtag, *fid, *mode ) ; if( *fid >= _9P_FID_PER_CONN ) { err = ERANGE ; rc = _9p_rerror( preq9p, msgtag, &err, plenout, preply ) ; return rc ; } pfid = &preq9p->pconn->fids[*fid] ; _9p_tools_acess2fsal( mode, &fsalaccess ) ; /* Perform the 'access' call */ if(cache_inode_access( pfid->pentry, fsalaccess, pwkrdata->ht, &pwkrdata->cache_inode_client, &pfid->fsal_op_context, &cache_status ) != CACHE_INODE_SUCCESS ) { err = EPERM ; rc = _9p_rerror( preq9p, msgtag, &err, plenout, preply ) ; return rc ; } /* iounit = 0 by default */ pfid->specdata.iounit = 0 ; /* Build the reply */ _9p_setinitptr( cursor, preply, _9P_RLOPEN ) ; _9p_setptr( cursor, msgtag, u16 ) ; _9p_setqid( cursor, pfid->qid ) ; _9p_setptr( cursor, &pfid->specdata.iounit, u32 ) ; _9p_setendptr( cursor, preply ) ; _9p_checkbound( cursor, preply, plenout ) ; LogDebug( COMPONENT_9P, "RLOPEN: tag=%u fid=%u qid=(type=%u,version=%u,path=%llu) iounit=%u", *msgtag, *fid, (u32)pfid->qid.type, pfid->qid.version, (unsigned long long)pfid->qid.path, pfid->specdata.iounit ) ; return 1 ; }
int _9p_getattr( _9p_request_data_t * preq9p, void * pworker_data, u32 * plenout, char * preply) { char * cursor = preq9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE ; u16 * msgtag = NULL ; u32 * fid = NULL ; u64 * request_mask = NULL ; _9p_fid_t * pfid = NULL ; int rc = 0 ; int err = 0 ; u64 * valid = NULL ; u32 * mode = NULL ; u32 * uid = NULL ; u32 * gid = NULL ; u64 * nlink = NULL ; u64 * rdev = NULL ; u64 * size = NULL ; u64 *blksize = NULL ; u64 * blocks = NULL ; u64 * atime_sec = NULL ; u64 * atime_nsec = NULL ; u64 * mtime_sec = NULL ; u64 * mtime_nsec = NULL ; u64 * ctime_sec = NULL ; u64 * ctime_nsec = NULL ; u64 * btime_sec = NULL; u64 * btime_nsec = NULL; u64 * gen = NULL; u64 * data_version = NULL; if ( !preq9p || !pworker_data || !plenout || !preply ) return -1 ; /* Get data */ _9p_getptr( cursor, msgtag, u16 ) ; _9p_getptr( cursor, fid, u32 ) ; _9p_getptr( cursor, request_mask, u64 ) ; LogDebug( COMPONENT_9P, "TGETATTR: tag=%u fid=%u request_mask=0x%llx", (u32)*msgtag, *fid, (unsigned long long)*request_mask ) ; if( *fid >= _9P_FID_PER_CONN ) { err = ERANGE ; rc = _9p_rerror( preq9p, msgtag, &err, plenout, preply ) ; return rc ; } pfid = &preq9p->pconn->fids[*fid] ; /* Attach point is found, build the requested attributes */ valid = request_mask ; /* FSAL covers all 9P attributes */ mode = (*request_mask & _9P_GETATTR_RDEV)?(u32 *)&pfid->attr.st_mode:&zero32 ; uid = (*request_mask & _9P_GETATTR_UID)?(u32 *)&pfid->attr.st_uid:&zero32 ; gid = (*request_mask & _9P_GETATTR_GID)?(u32 *)&pfid->attr.st_gid:&zero32 ; nlink = (*request_mask & _9P_GETATTR_NLINK)?(u64 *)&pfid->attr.st_nlink:&zero64 ; rdev = (*request_mask & _9P_GETATTR_RDEV)?(u64 *)&pfid->attr.st_rdev:&zero64 ; size = (*request_mask & _9P_GETATTR_SIZE)?(u64 *)&pfid->attr.st_size:&zero64 ; blksize = (*request_mask & _9P_GETATTR_BLOCKS)?(u64 *)&pfid->attr.st_blksize:&zero64 ; blocks = (*request_mask & _9P_GETATTR_BLOCKS)?(u64 *)&pfid->attr.st_blocks:&zero64 ; atime_sec = (*request_mask & _9P_GETATTR_ATIME )?(u64 *)&pfid->attr.st_atime:&zero64 ; atime_nsec = &zero64 ; mtime_sec = (*request_mask & _9P_GETATTR_MTIME )?(u64 *)&pfid->attr.st_mtime:&zero64 ; mtime_nsec = &zero64 ; ctime_sec = (*request_mask & _9P_GETATTR_CTIME )?(u64 *)&pfid->attr.st_ctime:&zero64 ; ctime_nsec = &zero64 ; /* Not yet supported attributes */ btime_sec = &zero64 ; btime_nsec = &zero64 ; gen = &zero64 ; data_version = &zero64 ; /* Build the reply */ _9p_setinitptr( cursor, preply, _9P_RGETATTR ) ; _9p_setptr( cursor, msgtag, u16 ) ; _9p_setptr( cursor, valid, u64 ) ; _9p_setqid( cursor, pfid->qid ) ; _9p_setptr( cursor, mode, u32 ) ; _9p_setptr( cursor, uid, u32 ) ; _9p_setptr( cursor, gid, u32 ) ; _9p_setptr( cursor, nlink, u64 ) ; _9p_setptr( cursor, rdev, u64 ) ; _9p_setptr( cursor, size, u64 ) ; _9p_setptr( cursor, blksize, u64 ) ; _9p_setptr( cursor, blocks, u64 ) ; _9p_setptr( cursor, atime_sec, u64 ) ; _9p_setptr( cursor, atime_nsec, u64 ) ; _9p_setptr( cursor, mtime_sec, u64 ) ; _9p_setptr( cursor, mtime_nsec, u64 ) ; _9p_setptr( cursor, ctime_sec, u64 ) ; _9p_setptr( cursor, ctime_nsec, u64 ) ; _9p_setptr( cursor, btime_sec, u64 ) ; _9p_setptr( cursor, btime_nsec, u64 ) ; _9p_setptr( cursor, gen, u64 ) ; _9p_setptr( cursor, data_version, u64 ) ; _9p_setendptr( cursor, preply ) ; _9p_checkbound( cursor, preply, plenout ) ; LogDebug( COMPONENT_9P, "RGETATTR: tag=%u valid=0x%llx qid=(type=%u,version=%u,path=%llu) mode=0%o uid=%u gid=%u nlink=%llu" " rdev=%llu size=%llu blksize=%llu blocks=%llu atime=(%llu,%llu) mtime=(%llu,%llu) ctime=(%llu,%llu)" " btime=(%llu,%llu) gen=%llu, data_version=%llu", *msgtag, (unsigned long long)*valid, (u32)pfid->qid.type, pfid->qid.version, (unsigned long long)pfid->qid.path, *mode, *uid, *gid, (unsigned long long)*nlink, (unsigned long long)*rdev, (unsigned long long)*size, (unsigned long long)*blksize, (unsigned long long)*blocks, (unsigned long long)*atime_sec, (unsigned long long)*atime_nsec, (unsigned long long)*mtime_sec, (unsigned long long)*mtime_nsec, (unsigned long long)*ctime_sec, (unsigned long long)*ctime_nsec, (unsigned long long)*btime_sec, (unsigned long long)*btime_nsec, (unsigned long long)*gen, (unsigned long long)*data_version ) ; return 1 ; }
int _9p_attach( _9p_request_data_t * preq9p, void * pworker_data, u32 * plenout, char * preply) { char * cursor = preq9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE ; nfs_worker_data_t * pwkrdata = (nfs_worker_data_t *)pworker_data ; u16 * msgtag = NULL ; u32 * fid = NULL ; u32 * afid = NULL ; u16 * uname_len = NULL ; char * uname_str = NULL ; u16 * aname_len = NULL ; char * aname_str = NULL ; u32 * n_aname = NULL ; fsal_attrib_list_t fsalattr ; int rc = 0 ; u32 err = 0 ; _9p_fid_t * pfid = NULL ; exportlist_t * pexport = NULL; unsigned int found = FALSE; cache_inode_status_t cache_status ; cache_inode_fsal_data_t fsdata ; if ( !preq9p || !pworker_data || !plenout || !preply ) return -1 ; /* Get data */ _9p_getptr( cursor, msgtag, u16 ) ; _9p_getptr( cursor, fid, u32 ) ; _9p_getptr( cursor, afid, u32 ) ; _9p_getstr( cursor, uname_len, uname_str ) ; _9p_getstr( cursor, aname_len, aname_str ) ; _9p_getptr( cursor, n_aname, u32 ) ; LogDebug( COMPONENT_9P, "TATTACH: tag=%u fid=%u afid=%d uname='%.*s' aname='%.*s' n_uname=%d", (u32)*msgtag, *fid, *afid, (int)*uname_len, uname_str, (int)*aname_len, aname_str, *n_aname ) ; /* * Find the export for the aname (using as well Path or Tag ) */ for( pexport = nfs_param.pexportlist; pexport != NULL; pexport = pexport->next) { if(aname_str[0] != '/') { /* The input value may be a "Tag" */ if(!strncmp(aname_str, pexport->FS_tag, strlen( pexport->FS_tag ) ) ) { found = TRUE ; break; } } else { if(!strncmp(aname_str, pexport->fullpath, strlen( pexport->fullpath ) ) ) { found = TRUE ; break; } } } /* for */ /* Did we find something ? */ if( found == FALSE ) { err = ENOENT ; rc = _9p_rerror( preq9p, msgtag, &err, plenout, preply ) ; return rc ; } if( *fid >= _9P_FID_PER_CONN ) { err = ERANGE ; rc = _9p_rerror( preq9p, msgtag, &err, plenout, preply ) ; return rc ; } /* Set pexport and fid id in fid */ pfid= &preq9p->pconn->fids[*fid] ; pfid->pexport = pexport ; pfid->fid = *fid ; #ifdef _USE_SHARED_FSAL /* At this step, the export entry is known and it's required to use the right fsalid */ FSAL_SetId( pexport->fsalid ) ; memcpy( &pfid->fsal_op_context, &pwkrdata->thread_fsal_context[pexport->fsalid], sizeof( fsal_op_context_t ) ) ; #else memcpy( &pfid->fsal_op_context, &pwkrdata->thread_fsal_context, sizeof( fsal_op_context_t ) ) ; #endif /* Is user name provided as a string or as an uid ? */ if( *uname_len != 0 ) { /* Build the fid creds */ if( ( err = _9p_tools_get_fsal_op_context_by_name( *uname_len, uname_str, pfid ) ) != 0 ) { err = -err ; /* The returned value from 9p service functions is always negative is case of errors */ rc = _9p_rerror( preq9p, msgtag, &err, plenout, preply ) ; return rc ; } } else { /* Build the fid creds */ if( ( err = _9p_tools_get_fsal_op_context_by_uid( *n_aname, pfid ) ) != 0 ) { err = -err ; /* The returned value from 9p service functions is always negative is case of errors */ rc = _9p_rerror( preq9p, msgtag, &err, plenout, preply ) ; return rc ; } } /* Get the related pentry */ memcpy( (char *)&fsdata.handle, (char *)pexport->proot_handle, sizeof( fsal_handle_t ) ) ; fsdata.cookie = 0; pfid->pentry = cache_inode_get( &fsdata, pexport->cache_inode_policy, &fsalattr, pwkrdata->ht, &pwkrdata->cache_inode_client, &pfid->fsal_op_context, &cache_status ) ; if( pfid->pentry == NULL ) { err = _9p_tools_errno( cache_status ) ; ; rc = _9p_rerror( preq9p, msgtag, &err, plenout, preply ) ; return rc ; } /* Compute the qid */ pfid->qid.type = _9P_QTDIR ; pfid->qid.version = 0 ; /* No cache, we want the client to stay synchronous with the server */ pfid->qid.path = fsalattr.fileid ; /* Cache the attr */ _9p_tools_fsal_attr2stat( &fsalattr, &pfid->attr ) ; /* Build the reply */ _9p_setinitptr( cursor, preply, _9P_RATTACH ) ; _9p_setptr( cursor, msgtag, u16 ) ; _9p_setqid( cursor, pfid->qid ) ; _9p_setendptr( cursor, preply ) ; _9p_checkbound( cursor, preply, plenout ) ; LogDebug( COMPONENT_9P, "RATTACH: tag=%u fid=%u qid=(type=%u,version=%u,path=%llu)", *msgtag, *fid, (u32)pfid->qid.type, pfid->qid.version, (unsigned long long)pfid->qid.path ) ; return 1 ; }
int _9p_mkdir(struct _9p_request_data *req9p, void *worker_data, u32 *plenout, char *preply) { char *cursor = req9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE; u16 *msgtag = NULL; u32 *fid = NULL; u32 *mode = NULL; u32 *gid = NULL; u16 *name_len = NULL; char *name_str = NULL; struct _9p_fid *pfid = NULL; struct _9p_qid qid_newdir; cache_entry_t *pentry_newdir = NULL; char dir_name[MAXNAMLEN]; uint64_t fileid; cache_inode_status_t cache_status; /* Get data */ _9p_getptr(cursor, msgtag, u16); _9p_getptr(cursor, fid, u32); _9p_getstr(cursor, name_len, name_str); _9p_getptr(cursor, mode, u32); _9p_getptr(cursor, gid, u32); LogDebug(COMPONENT_9P, "TMKDIR: tag=%u fid=%u name=%.*s mode=0%o gid=%u", (u32) *msgtag, *fid, *name_len, name_str, *mode, *gid); if (*fid >= _9P_FID_PER_CONN) return _9p_rerror(req9p, worker_data, msgtag, ERANGE, plenout, preply); pfid = req9p->pconn->fids[*fid]; /* Check that it is a valid fid */ if (pfid == NULL || pfid->pentry == NULL) { LogDebug(COMPONENT_9P, "request on invalid fid=%u", *fid); return _9p_rerror(req9p, worker_data, msgtag, EIO, plenout, preply); } snprintf(dir_name, MAXNAMLEN, "%.*s", *name_len, name_str); op_ctx = &pfid->op_context; /* Create the directory */ /* BUGAZOMEU: @todo : the gid parameter is not used yet */ cache_status = cache_inode_create(pfid->pentry, dir_name, DIRECTORY, *mode, NULL, &pentry_newdir); if (pentry_newdir == NULL) return _9p_rerror(req9p, worker_data, msgtag, _9p_tools_errno(cache_status), plenout, preply); /* This is not a TATTACH fid */ pfid->from_attach = FALSE; cache_status = cache_inode_fileid(pentry_newdir, &fileid); /* put the entry: * we don't want to remember it even if cache_inode_fileid fails. */ cache_inode_put(pentry_newdir); if (cache_status != CACHE_INODE_SUCCESS) return _9p_rerror(req9p, worker_data, msgtag, _9p_tools_errno(cache_status), plenout, preply); /* Build the qid */ qid_newdir.type = _9P_QTDIR; qid_newdir.version = 0; qid_newdir.path = fileid; /* Build the reply */ _9p_setinitptr(cursor, preply, _9P_RMKDIR); _9p_setptr(cursor, msgtag, u16); _9p_setqid(cursor, qid_newdir); _9p_setendptr(cursor, preply); _9p_checkbound(cursor, preply, plenout); LogDebug(COMPONENT_9P, "RMKDIR: tag=%u fid=%u name=%.*s qid=(type=%u,version=%u,path=%llu)", (u32) *msgtag, *fid, *name_len, name_str, qid_newdir.type, qid_newdir.version, (unsigned long long)qid_newdir.path); return 1; }