Пример #1
0
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 ;
}
Пример #2
0
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 ;
}
Пример #3
0
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 ;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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 ;
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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 ;
}
Пример #11
0
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 ;
}
Пример #12
0
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 ;
}
Пример #13
0
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;
}