Example #1
0
int nlm4_Test(nfs_arg_t * parg /* IN     */ ,
              exportlist_t * pexport /* IN     */ ,
              fsal_op_context_t * pcontext /* IN     */ ,
              cache_inode_client_t * pclient /* INOUT  */ ,
              hash_table_t * ht /* INOUT  */ ,
              struct svc_req *preq /* IN     */ ,
              nfs_res_t * pres /* OUT    */ )
{
  nlm4_testargs *arg;
  cache_entry_t *pentry;
  fsal_attrib_list_t attr;
  nlm_lock_entry_t *nlm_entry;
  cache_inode_status_t cache_status;
  cache_inode_fsal_data_t fsal_data;

  LogFullDebug(COMPONENT_NFSPROTO,
                    "REQUEST PROCESSING: Calling nlm_Test");

  if(in_nlm_grace_period())
    {
      pres->res_nlm4test.test_stat.stat = NLM4_DENIED_GRACE_PERIOD;
      return NFS_REQ_OK;
    }

  /* Convert file handle into a cache entry */
  arg = &parg->arg_nlm4_test;
  if(!nfs3_FhandleToFSAL((nfs_fh3 *) & (arg->alock.fh), &fsal_data.handle, pcontext))
    {
      /* handle is not valid */
      pres->res_nlm4test.test_stat.stat = NLM4_STALE_FH;
      /*
       * Should we do a REQ_OK so that the client get
       * a response ? FIXME!!
       */
      return NFS_REQ_DROP;
    }
  /* Now get the cached inode attributes */
  fsal_data.cookie = DIR_START;
  if((pentry = cache_inode_get(&fsal_data, &attr, ht,
                               pclient, pcontext, &cache_status)) == NULL)
    {
      /* handle is not valid */
      pres->res_nlm4test.test_stat.stat = NLM4_STALE_FH;
      return NFS_REQ_OK;
    }
  nlm_entry = nlm_overlapping_entry(&(arg->alock), arg->exclusive);
  if(!nlm_entry)
    {
      pres->res_nlm4test.test_stat.stat = NLM4_GRANTED;
    }
  else
    {
      pres->res_nlm4test.test_stat.stat = NLM4_DENIED;
      nlm_lock_entry_to_nlm_holder(nlm_entry,
                                   &pres->res_nlm4test.test_stat.nlm4_testrply_u.holder);
      nlm_lock_entry_dec_ref(nlm_entry);
    }

  return NFS_REQ_OK;
}
Example #2
0
int nfs3_Pathconf(nfs_arg_t * parg,
                  exportlist_t * pexport,
                  fsal_op_context_t * pcontext,
                  cache_inode_client_t * pclient,
                  hash_table_t * ht, struct svc_req *preq, nfs_res_t * pres)
{
  static char __attribute__ ((__unused__)) funcName[] = "nfs3_Pathconf";

  cache_inode_status_t cache_status;
  cache_entry_t *pentry = NULL;
  cache_inode_fsal_data_t fsal_data;
  fsal_attrib_list_t attr;
  fsal_staticfsinfo_t * pstaticinfo = pcontext->export_context->fe_static_fs_info;

  if(isDebug(COMPONENT_NFSPROTO))
    {
      char str[LEN_FH_STR];
      sprint_fhandle3(str, &(parg->arg_pathconf3.object));
      LogDebug(COMPONENT_NFSPROTO,
               "REQUEST PROCESSING: Calling nfs3_Pathconf handle: %s", str);
    }

  /* to avoid setting it on each error case */
  pres->res_pathconf3.PATHCONF3res_u.resfail.obj_attributes.attributes_follow = FALSE;

  /* Convert file handle into a fsal_handle */
  if(nfs3_FhandleToFSAL(&(parg->arg_pathconf3.object), &fsal_data.handle, pcontext) == 0)
    return NFS_REQ_DROP;

  /* Set cookie to zero */
  fsal_data.cookie = DIR_START;

  /* Get the entry in the cache_inode */
  if((pentry = cache_inode_get( &fsal_data,
                                pexport->cache_inode_policy,
                                &attr, 
                                ht, 
                                pclient, 
                                pcontext, 
                                &cache_status)) == NULL)
    {
      /* Stale NFS FH ? */
      pres->res_pathconf3.status = NFS3ERR_STALE;
      return NFS_REQ_OK;
    }

  /* Build post op file attributes */
  nfs_SetPostOpAttr(pcontext, pexport,
                    pentry,
                    &attr, &(pres->res_pathconf3.PATHCONF3res_u.resok.obj_attributes));

  pres->res_pathconf3.PATHCONF3res_u.resok.linkmax = pstaticinfo->maxlink;
  pres->res_pathconf3.PATHCONF3res_u.resok.name_max = pstaticinfo->maxnamelen;
  pres->res_pathconf3.PATHCONF3res_u.resok.no_trunc = pstaticinfo->no_trunc;
  pres->res_pathconf3.PATHCONF3res_u.resok.chown_restricted = pstaticinfo->chown_restricted;
  pres->res_pathconf3.PATHCONF3res_u.resok.case_insensitive = pstaticinfo->case_insensitive;
  pres->res_pathconf3.PATHCONF3res_u.resok.case_preserving = pstaticinfo->case_preserving;

  return NFS_REQ_OK;
}                               /* nfs3_Pathconf */
Example #3
0
int nfs3_Pathconf(nfs_arg_t * parg,
                  exportlist_t * pexport,
                  fsal_op_context_t * pcontext,
                  cache_inode_client_t * pclient,
                  hash_table_t * ht, struct svc_req *preq, nfs_res_t * pres)
{
  static char __attribute__ ((__unused__)) funcName[] = "nfs3_Pathconf";

  cache_inode_status_t cache_status;
  cache_entry_t *pentry = NULL;
  cache_inode_fsal_data_t fsal_data;
  fsal_attrib_list_t attr;
  fsal_staticfsinfo_t staticinfo;
  fsal_dynamicfsinfo_t dynamicinfo;

  /* to avoid setting it on each error case */
  pres->res_pathconf3.PATHCONF3res_u.resfail.obj_attributes.attributes_follow = FALSE;

  /* Convert file handle into a fsal_handle */
  if(nfs3_FhandleToFSAL(&(parg->arg_access3.object), &fsal_data.handle, pcontext) == 0)
    return NFS_REQ_DROP;

  /* Set cookie to zero */
  fsal_data.cookie = DIR_START;

  /* Get the entry in the cache_inode */
  if((pentry = cache_inode_get(&fsal_data,
                               &attr, ht, pclient, pcontext, &cache_status)) == NULL)
    {
      /* Stale NFS FH ? */
      pres->res_pathconf3.status = NFS3ERR_STALE;
      return NFS_REQ_OK;
    }

  /* Get the filesystem information */
  if(cache_inode_statfs(pentry, &staticinfo, &dynamicinfo, pcontext, &cache_status) !=
     CACHE_INODE_SUCCESS)
    {
      pres->res_pathconf3.status = nfs3_Errno(cache_status);
      return NFS_REQ_OK;
    }

  /* Build post op file attributes */
  nfs_SetPostOpAttr(pcontext, pexport,
                    pentry,
                    &attr, &(pres->res_pathconf3.PATHCONF3res_u.resok.obj_attributes));

  pres->res_pathconf3.PATHCONF3res_u.resok.linkmax = staticinfo.maxlink;
  pres->res_pathconf3.PATHCONF3res_u.resok.name_max = staticinfo.maxnamelen;
  pres->res_pathconf3.PATHCONF3res_u.resok.no_trunc = staticinfo.no_trunc;
  pres->res_pathconf3.PATHCONF3res_u.resok.chown_restricted = staticinfo.chown_restricted;
  pres->res_pathconf3.PATHCONF3res_u.resok.case_insensitive = staticinfo.case_insensitive;
  pres->res_pathconf3.PATHCONF3res_u.resok.case_preserving = staticinfo.case_preserving;

  return NFS_REQ_OK;
}                               /* nfs3_Pathconf */
Example #4
0
fsal_status_t dumb_fsal_up_invalidate(fsal_up_event_data_t * pevdata)
{
  cache_inode_status_t cache_status;
  cache_entry_t *pentry = NULL;
  fsal_attrib_list_t attr;

  memset(&attr, 0, sizeof(fsal_attrib_list_t));

  /* Avoid dir cont check in cache_inode_get() */
  pevdata->event_context.fsal_data.cookie = DIR_START;
      LogDebug(COMPONENT_FSAL_UP,
               "FSAL_UP_DUMB: calling cache_inode_get()");
  pentry = cache_inode_get(&pevdata->event_context.fsal_data, cachepol,
                           &attr, pevdata->event_context.ht, NULL, NULL,
                           &cache_status);
  if(pentry == NULL)
    {
      LogDebug(COMPONENT_FSAL_UP,
               "FSAL_UP_DUMB: cache inode get failed.");
      /* Not an error. Expecting some nodes will not have it in cache in
       * a cluster. */
      ReturnCode(ERR_FSAL_NO_ERROR, 0);
    }

  LogDebug(COMPONENT_FSAL_UP,
          "FSAL_UP_DUMB: Invalidate cache found entry %p type %u",
          pentry, pentry->internal_md.type);

  /* Lock the entry */
  P_w(&pentry->lock);
      LogDebug(COMPONENT_FSAL_UP,
               "FSAL_UP_DUMB: setting state to STALE");
  pentry->internal_md.valid_state = STALE;
  if(pentry->internal_md.type == DIRECTORY)
    {
      pentry->object.dir.has_been_readdir = CACHE_INODE_RENEW_NEEDED;
      LogDebug(COMPONENT_FSAL_UP,
              "FSAL_CB_DUMB: Invalidate reset directory.");
    }
  V_w(&pentry->lock);

  ReturnCode(ERR_FSAL_NO_ERROR, 0);
}
Example #5
0
fsal_status_t dumb_fsal_up_lock_avail(fsal_up_event_data_t * pevdata)
{
#ifdef _USE_BLOCKING_LOCKS
  cache_inode_status_t   cache_status;
  cache_entry_t        * pentry = NULL;
  fsal_attrib_list_t     attr;

  /* Avoid dir cont check in cache_inode_get() */
  pevdata->event_context.fsal_data.cookie = DIR_START;
      LogDebug(COMPONENT_FSAL_UP,
               "FSAL_UP_DUMB: calling cache_inode_get()");
  pentry = cache_inode_get(&pevdata->event_context.fsal_data, cachepol,
                           &attr, pevdata->event_context.ht, NULL, NULL,
                           &cache_status);
  if(pentry == NULL)
    {
      LogDebug(COMPONENT_FSAL_UP,
               "FSAL_UP_DUMB: cache inode get failed.");
      /* Not an error. Expecting some nodes will not have it in cache in
       * a cluster. */
      ReturnCode(ERR_FSAL_NO_ERROR, 0);
    }

  LogDebug(COMPONENT_FSAL_UP,
           "FSAL_UP_DUMB: Lock Available found entry %p",
           pentry);

  available_blocked_lock_upcall(pentry,
                                pevdata->type.lock_grant.lock_owner,
                                &pevdata->type.lock_grant.lock_param,
                                NULL);
                            

  ReturnCode(ERR_FSAL_NO_ERROR, 0);
#else
  INVALIDATE_STUB;
#endif
}
fsal_status_t dumb_fsal_up_lock_grant(fsal_up_event_data_t * pevdata)
{
#ifdef _USE_BLOCKING_LOCKS
  cache_inode_status_t   cache_status;
  cache_entry_t        * pentry = NULL;
  fsal_attrib_list_t     attr;

  LogFullDebug(COMPONENT_FSAL_UP,
               "FSAL_UP_DUMB: calling cache_inode_get()");
  pentry = cache_inode_get(&pevdata->event_context.fsal_data,
                           &attr, NULL, NULL,
                           &cache_status);
  if(pentry == NULL)
    {
      LogDebug(COMPONENT_FSAL_UP,
               "FSAL_UP_DUMB: cache inode get failed.");
      /* Not an error. Expecting some nodes will not have it in cache in
       * a cluster. */
      ReturnCode(ERR_FSAL_NO_ERROR, 0);
    }

  LogDebug(COMPONENT_FSAL_UP,
           "FSAL_UP_DUMB: Lock Grant found entry %p",
           pentry);

  grant_blocked_lock_upcall(pentry,
                            pevdata->type.lock_grant.lock_owner,
                            &pevdata->type.lock_grant.lock_param);


  if(pentry)
    cache_inode_put(pentry);

  ReturnCode(ERR_FSAL_NO_ERROR, 0);
#else
  INVALIDATE_STUB;
#endif
}
/**
 *
 * cache_content_crash_recover: recovers the data cache and the associated inode after a crash.
 *
 * @param pclient [IN]  ressource allocated by the client for the nfs management.
 * @pstatus [OUT] returned status.
 *
 * @return CACHE_CONTENT_SUCCESS is successful.
 *
 */
cache_content_status_t cache_content_crash_recover(unsigned short exportid,
                                                   unsigned int index,
                                                   unsigned int mod,
                                                   cache_content_client_t * pclient_data,
                                                   cache_inode_client_t * pclient_inode,
                                                   hash_table_t * ht,
                                                   fsal_op_context_t * pcontext,
                                                   cache_content_status_t * pstatus)
{
  DIR *cache_directory;
  cache_content_dirinfo_t export_directory;

  char cache_exportdir[MAXPATHLEN];
  char fullpath[MAXPATHLEN];

  struct dirent *direntp;
  struct dirent dirent_export;

  int found_export_id;
  u_int64_t inum;

  off_t size_in_cache;

  cache_entry_t inode_entry;
  cache_entry_t *pentry = NULL;
  cache_content_entry_t *pentry_content = NULL;
  cache_inode_status_t cache_inode_status;
  cache_content_status_t cache_content_status;

  fsal_attrib_list_t fsal_attr;
  cache_inode_fsal_data_t fsal_data;

  *pstatus = CACHE_CONTENT_SUCCESS;

  /* Open the cache directory */
  if((cache_directory = opendir(pclient_data->cache_dir)) == NULL)
    {
      *pstatus = CACHE_CONTENT_LOCAL_CACHE_ERROR;
      return *pstatus;
    }
  /* read the cache directory */
  while((direntp = readdir(cache_directory)) != NULL)
    {

      /* . and .. are of no interest */
      if(!strcmp(direntp->d_name, ".") || !strcmp(direntp->d_name, ".."))
        continue;

      if((found_export_id = cache_content_get_export_id(direntp->d_name)) >= 0)
        {
          LogEvent(COMPONENT_CACHE_CONTENT,
                            "Directory cache for Export ID %d has been found",
                            found_export_id);
          snprintf(cache_exportdir, MAXPATHLEN, "%s/%s", pclient_data->cache_dir,
                   direntp->d_name);

          if(cache_content_local_cache_opendir(cache_exportdir, &(export_directory)) ==
             FALSE)
            {
              *pstatus = CACHE_CONTENT_LOCAL_CACHE_ERROR;
              closedir(cache_directory);
              return *pstatus;
            }

          /* Reads the directory content (a single thread for the moment) */

          while(cache_content_local_cache_dir_iter
                (&export_directory, &dirent_export, index, mod))
            {
              /* . and .. are of no interest */
              if(!strcmp(dirent_export.d_name, ".")
                 || !strcmp(dirent_export.d_name, ".."))
                continue;

              if((inum = cache_content_get_inum(dirent_export.d_name)) > 0)
                {
                  LogEvent(COMPONENT_CACHE_CONTENT,
                                    "Cache entry for File ID %llx has been found", inum);

                  /* Get the content of the file */
                  sprintf(fullpath, "%s/%s/%s", pclient_data->cache_dir, direntp->d_name,
                          dirent_export.d_name);

                  if((cache_inode_status = cache_inode_reload_content(fullpath,
                                                                      &inode_entry)) !=
                     CACHE_INODE_SUCCESS)
                    {
                      LogMajor(COMPONENT_CACHE_CONTENT,
                                        "File Content Cache record for File ID %llx is unreadable",
                                        inum);
                      continue;
                    }
                  else
                    LogMajor(COMPONENT_CACHE_CONTENT,
                                      "File Content Cache record for File ID %llx : READ OK",
                                      inum);

                  /* Populating the cache_inode... */
                  fsal_data.handle = inode_entry.object.file.handle;
                  fsal_data.cookie = 0;

                  if((pentry = cache_inode_get(&fsal_data,
                                               &fsal_attr,
                                               ht,
                                               pclient_inode,
                                               pcontext, &cache_inode_status)) == NULL)
                    {
                      LogCrit(COMPONENT_CACHE_CONTENT,
                                   "Error adding cached inode for file ID %llx, error=%d",
                                   inum, cache_inode_status);
                      continue;
                    }
                  else
                    LogEvent(COMPONENT_CACHE_CONTENT,
                                      "Cached inode added successfully for file ID %llx",
                                      inum);

                  /* Get the size from the cache */
                  if((size_in_cache =
                      cache_content_recover_size(cache_exportdir, inum)) == -1)
                    {
                      LogCrit(COMPONENT_CACHE_CONTENT,
                                   "Error when recovering size for file ID %llx", inum);
                    }
                  else
                    pentry->object.file.attributes.filesize = (fsal_size_t) size_in_cache;

                  /* Adding the cached entry to the data cache */
                  if((pentry_content = cache_content_new_entry(pentry,
                                                               NULL,
                                                               pclient_data,
                                                               RECOVER_ENTRY,
                                                               pcontext,
                                                               &cache_content_status)) ==
                     NULL)
                    {
                      LogCrit(COMPONENT_CACHE_CONTENT,
                                   "Error adding cached data for file ID %llx, error=%d",
                                   inum, cache_inode_status);
                      continue;
                    }
                  else
                    LogEvent(COMPONENT_CACHE_CONTENT,
                                      "Cached data added successfully for file ID %llx",
                                      inum);

                  if((cache_content_status =
                      cache_content_valid(pentry_content, CACHE_CONTENT_OP_GET,
                                          pclient_data)) != CACHE_CONTENT_SUCCESS)
                    {
                      *pstatus = cache_content_status;
                      return *pstatus;
                    }

                }

            }                   /*  while( ( dirent_export = readdir( export_directory ) ) != NULL ) */

          /* Close the export cache directory */
          cache_content_local_cache_closedir(&export_directory);

        }                       /* if( ( found_export_id = cache_content_get_export_id( direntp->d_name ) ) > 0 ) */
    }                           /* while( ( direntp = readdir( cache_directory ) ) != NULL ) */

  /* Close the cache directory */
  closedir(cache_directory);

  return *pstatus;
}                               /* cache_content_crash_recover */
Example #8
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 ;
}
Example #9
0
int nfs3_Fsinfo(nfs_arg_t * parg,
                exportlist_t * pexport,
                fsal_op_context_t * pcontext,
                cache_inode_client_t * pclient,
                hash_table_t * ht, struct svc_req *preq, nfs_res_t * pres)
{
  static char __attribute__ ((__unused__)) funcName[] = "nfs3_Fsinfo";

  cache_inode_status_t cache_status;
  cache_entry_t *pentry = NULL;
  cache_inode_fsal_data_t fsal_data;
  fsal_attrib_list_t attr;

  if(isDebug(COMPONENT_NFSPROTO))
    {
      char str[LEN_FH_STR];
      sprint_fhandle3(str, &(parg->arg_fsinfo3.fsroot));
      LogDebug(COMPONENT_NFSPROTO,
               "REQUEST PROCESSING: Calling nfs3_Fsinfo handle: %s", str);
    }

  /* to avoid setting it on each error case */
  pres->res_fsinfo3.FSINFO3res_u.resfail.obj_attributes.attributes_follow = FALSE;

  /* Convert file handle into a fsal_handle */
  if(nfs3_FhandleToFSAL(&(parg->arg_fsinfo3.fsroot), &fsal_data.handle, pcontext) == 0)
    return NFS_REQ_DROP;

  /* Set the cookie */
  fsal_data.cookie = DIR_START;

  /* Get the entry in the cache_inode */
  if((pentry = cache_inode_get( &fsal_data,
                                pexport->cache_inode_policy,
                                &attr, 
                                ht, 
                                pclient, 
                                pcontext, 
                                &cache_status)) == NULL)
    {
      /* Stale NFS FH ? */
      pres->res_fsinfo3.status = NFS3ERR_STALE;
      return NFS_REQ_OK;
    }

  /*
   * New fields were added to nfs_config_t to handle this value. We use
   * them 
   */

#define FSINFO_FIELD pres->res_fsinfo3.FSINFO3res_u.resok
  FSINFO_FIELD.rtmax = pexport->MaxRead;
  FSINFO_FIELD.rtpref = pexport->PrefRead;

  /* This field is generally unused, it will be removed in V4 */
  FSINFO_FIELD.rtmult = DEV_BSIZE;

  FSINFO_FIELD.wtmax = pexport->MaxWrite;
  FSINFO_FIELD.wtpref = pexport->PrefWrite;

  /* This field is generally unused, it will be removed in V4 */
  FSINFO_FIELD.wtmult = DEV_BSIZE;

  FSINFO_FIELD.dtpref = pexport->PrefReaddir;

  FSINFO_FIELD.maxfilesize = FSINFO_MAX_FILESIZE;
  FSINFO_FIELD.time_delta.seconds = 1;
  FSINFO_FIELD.time_delta.nseconds = 0;

  LogFullDebug(COMPONENT_NFSPROTO,
               "rtmax = %d | rtpref = %d | trmult = %d",
               FSINFO_FIELD.rtmax,
               FSINFO_FIELD.rtpref,
               FSINFO_FIELD.rtmult);
  LogFullDebug(COMPONENT_NFSPROTO,
               "wtmax = %d | wtpref = %d | wrmult = %d",
               FSINFO_FIELD.wtmax,
               FSINFO_FIELD.wtpref,
               FSINFO_FIELD.wtmult);
  LogFullDebug(COMPONENT_NFSPROTO,
               "dtpref = %d | maxfilesize = %llu ",
               FSINFO_FIELD.dtpref,
               FSINFO_FIELD.maxfilesize);

  /*
   * Allow all kinds of operations to be performed on the server
   * through NFS v3 
   */
  FSINFO_FIELD.properties = FSF3_LINK | FSF3_SYMLINK | FSF3_HOMOGENEOUS | FSF3_CANSETTIME;

  nfs_SetPostOpAttr(pcontext, pexport,
                    pentry,
                    &attr, &(pres->res_fsinfo3.FSINFO3res_u.resok.obj_attributes));
  pres->res_fsinfo3.status = NFS3_OK;

  return NFS_REQ_OK;
}                               /* nfs3_Fsinfo */
Example #10
0
cache_entry_t *cache_inode_get_located(cache_inode_fsal_data_t * pfsdata,
                                       cache_entry_t * plocation, 
                                       cache_inode_policy_t policy,
                                       fsal_attrib_list_t * pattr,
                                       hash_table_t * ht,
                                       cache_inode_client_t * pclient,
                                       fsal_op_context_t * pcontext,
                                       cache_inode_status_t * pstatus)
{
  hash_buffer_t key, value;
  cache_entry_t *pentry = NULL;
  fsal_status_t fsal_status;
  cache_inode_create_arg_t create_arg;
  cache_inode_file_type_t type;
  int hrc = 0;
  fsal_attrib_list_t fsal_attributes;
  cache_inode_fsal_data_t *ppoolfsdata = NULL;

  memset(&create_arg, 0, sizeof(create_arg));

  /* Set the return default to CACHE_INODE_SUCCESS */
  *pstatus = CACHE_INODE_SUCCESS;

  /* stats */
  /* cache_invalidate calls this with no context or client */
  if (pclient) {
    pclient->stat.nb_call_total += 1;
    pclient->stat.func_stats.nb_call[CACHE_INODE_GET] += 1;
  }

  /* Turn the input to a hash key */
  if(cache_inode_fsaldata_2_key(&key, pfsdata, pclient))
    {
      *pstatus = CACHE_INODE_UNAPPROPRIATED_KEY;

      /* stats */
      /* cache_invalidate calls this with no context or client */
      if (pclient) {
	pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_GET] += 1;
	ppoolfsdata = (cache_inode_fsal_data_t *) key.pdata;
	ReleaseToPool(ppoolfsdata, &pclient->pool_key);
      }
      return NULL;
    }

  switch (hrc = HashTable_Get(ht, &key, &value))
    {
    case HASHTABLE_SUCCESS:
      /* Entry exists in the cache and was found */
      pentry = (cache_entry_t *) value.pdata;

      /* return attributes additionally */
      *pattr = pentry->attributes;

      if ( !pclient ) {
	/* invalidate. Just return it to mark it stale and go on. */
	return( pentry );
      }

      break;

    case HASHTABLE_ERROR_NO_SUCH_KEY:
      if ( !pclient ) {
	/* invalidate. Just return */
	return( NULL );
      }
      /* Cache miss, allocate a new entry */

      /* XXX I do not think this can happen with avl dirent cache */
      if(pfsdata->cookie != DIR_START)
        {
          /* added for sanity check */
          LogDebug(COMPONENT_CACHE_INODE,
                       "cache_inode_get: pfsdata->cookie != DIR_START (=%"PRIu64") on object whose type is %u",
                       pfsdata->cookie,
                       cache_inode_fsal_type_convert(fsal_attributes.type));

          pfsdata->cookie = DIR_START;

          /* Free this key */
          cache_inode_release_fsaldata_key(&key, pclient);

          /* redo the call */
          return cache_inode_get(pfsdata, policy, pattr, ht, pclient, pcontext, pstatus);
        }

      /* First, call FSAL to know what the object is */
      fsal_attributes.asked_attributes = pclient->attrmask;
      fsal_status = FSAL_getattrs(&pfsdata->handle, pcontext, &fsal_attributes);
      if(FSAL_IS_ERROR(fsal_status))
        {
          *pstatus = cache_inode_error_convert(fsal_status);

          LogDebug(COMPONENT_CACHE_INODE,
                   "cache_inode_get: cache_inode_status=%u fsal_status=%u,%u ",
                   *pstatus, fsal_status.major, fsal_status.minor);

          if(fsal_status.major == ERR_FSAL_STALE)
            {
              char handle_str[256];

              snprintHandle(handle_str, 256, &pfsdata->handle);
              LogEvent(COMPONENT_CACHE_INODE,
                       "cache_inode_get: Stale FSAL File Handle %s, fsal_status=(%u,%u)",
                       handle_str, fsal_status.major, fsal_status.minor);

              *pstatus = CACHE_INODE_FSAL_ESTALE;
            }

          /* stats */
          pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_GET] += 1;

          /* Free this key */
          cache_inode_release_fsaldata_key(&key, pclient);

          return NULL;
        }

      /* The type has to be set in the attributes */
      if(!FSAL_TEST_MASK(fsal_attributes.supported_attributes, FSAL_ATTR_TYPE))
        {
          *pstatus = CACHE_INODE_FSAL_ERROR;

          /* stats */
          pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_GET] += 1;

          /* Free this key */
          cache_inode_release_fsaldata_key(&key, pclient);

          return NULL;
        }

      /* Get the cache_inode file type */
      type = cache_inode_fsal_type_convert(fsal_attributes.type);

      if(type == SYMBOLIC_LINK)
        {
          if( CACHE_INODE_KEEP_CONTENT( policy ) )
           {
             FSAL_CLEAR_MASK(fsal_attributes.asked_attributes);
             FSAL_SET_MASK(fsal_attributes.asked_attributes, pclient->attrmask);
             fsal_status =
                FSAL_readlink(&pfsdata->handle, pcontext, &create_arg.link_content,
                              &fsal_attributes);
            }
          else
            { 
               fsal_status.major = ERR_FSAL_NO_ERROR ;
               fsal_status.minor = 0 ;
            }

          if(FSAL_IS_ERROR(fsal_status))
            {
              *pstatus = cache_inode_error_convert(fsal_status);

              /* stats */
              pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_GET] += 1;

              /* Free this key */
              cache_inode_release_fsaldata_key(&key, pclient);

              if(fsal_status.major == ERR_FSAL_STALE)
                {
                  cache_inode_status_t kill_status;

                  LogEvent(COMPONENT_CACHE_INODE,
                           "cache_inode_get: Stale FSAL File Handle detected for pentry = %p, fsal_status=(%u,%u)",
                           pentry, fsal_status.major, fsal_status.minor);

                  if(cache_inode_kill_entry(pentry, NO_LOCK, ht, pclient, &kill_status) !=
                     CACHE_INODE_SUCCESS)
                    LogCrit(COMPONENT_CACHE_INODE,
                            "cache_inode_get: Could not kill entry %p, status = %u, fsal_status=(%u,%u)",
                            pentry, kill_status, fsal_status.major, fsal_status.minor);

                  *pstatus = CACHE_INODE_FSAL_ESTALE;

                }

              return NULL;
            }
        }

      /* Add the entry to the cache */
      if ( type == 1)
	LogCrit(COMPONENT_CACHE_INODE,"inode get");

      if((pentry = cache_inode_new_entry( pfsdata,
                                          &fsal_attributes, 
                                          type,
                                          policy, 
                                          &create_arg, 
                                          NULL,    /* never used to add a new DIR_CONTINUE within this function */
                                          ht, 
                                          pclient, 
                                          pcontext, 
                                          FALSE,  /* This is a population, not a creation */
                                          pstatus ) ) == NULL )
        {
          /* stats */
          pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_GET] += 1;

          /* Free this key */
          cache_inode_release_fsaldata_key(&key, pclient);

          return NULL;
        }

      /* Set the returned attributes */
      *pattr = fsal_attributes;

      /* Now, exit the switch/case and returns */
      break;

    default:
      /* This should not happened */
      *pstatus = CACHE_INODE_INVALID_ARGUMENT;
      LogCrit(COMPONENT_CACHE_INODE,
              "cache_inode_get returning CACHE_INODE_INVALID_ARGUMENT - this should not have happened");

      if ( !pclient ) {
        /* invalidate. Just return */
        return( NULL );
      }

      /* stats */
      pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_GET] += 1;

      /* Free this key */
      cache_inode_release_fsaldata_key(&key, pclient);

      return NULL;
      break;
    }

  /* Want to ASSERT pclient at this point */
  *pstatus = CACHE_INODE_SUCCESS;
  
  if (pentry->object.symlink != NULL) {
  	int stop_here;
	stop_here = 1;
	if (stop_here) {
		stop_here = 2;
	}
  }

  /* valid the found entry, if this is not feasable, returns nothing to the client */
  if( plocation != NULL )
   {
     if( plocation != pentry )
      {
        P_w(&pentry->lock);
        if((*pstatus =
           cache_inode_valid(pentry, CACHE_INODE_OP_GET, pclient)) != CACHE_INODE_SUCCESS)
          {
            V_w(&pentry->lock);
            pentry = NULL;
          }
        V_w(&pentry->lock);
      }
   }

  /* stats */
  pclient->stat.func_stats.nb_success[CACHE_INODE_GET] += 1;

  /* Free this key */
  cache_inode_release_fsaldata_key(&key, pclient);

  return pentry;
}  /* cache_inode_get_located */
Example #11
0
int nlm_process_parameters(struct svc_req        * preq,
                           bool_t                  exclusive,
                           nlm4_lock             * alock,
                           fsal_lock_param_t     * plock,
                           cache_entry_t        ** ppentry,
                           fsal_op_context_t     * pcontext,
                           care_t                  care,
                           state_nsm_client_t   ** ppnsm_client,
                           state_nlm_client_t   ** ppnlm_client,
                           state_owner_t        ** ppowner,
                           state_block_data_t   ** ppblock_data)
{
  cache_inode_fsal_data_t fsal_data;
  fsal_attrib_list_t      attr;
  cache_inode_status_t    cache_status;
  SVCXPRT                *ptr_svc = preq->rq_xprt;
  int                     rc;

  *ppnsm_client = NULL;
  *ppnlm_client = NULL;
  *ppowner      = NULL;

  /* Convert file handle into a cache entry */
  if(alock->fh.n_len > MAX_NETOBJ_SZ ||
     !nfs3_FhandleToFSAL((nfs_fh3 *) &alock->fh, &fsal_data.fh_desc, pcontext))
    {
      /* handle is not valid */
      return NLM4_STALE_FH;
    }

  /* Now get the cached inode attributes */
  *ppentry = cache_inode_get(&fsal_data,
                             &attr,
                             pcontext,
                             NULL,
                             &cache_status);
  if(*ppentry == NULL)
    {
      /* handle is not valid */
      return NLM4_STALE_FH;
    }

  *ppnsm_client = get_nsm_client(care, ptr_svc, alock->caller_name);

  if(*ppnsm_client == NULL)
    {
      /* If NSM Client is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      if(care != CARE_NOT)
        rc = NLM4_DENIED_NOLOCKS;
      else
        rc = NLM4_GRANTED;

      goto out_put;
    }

  *ppnlm_client = get_nlm_client(care, ptr_svc, *ppnsm_client, alock->caller_name);

  if(*ppnlm_client == NULL)
    {
      /* If NLM Client is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      dec_nsm_client_ref(*ppnsm_client);

      if(care != CARE_NOT)
        rc = NLM4_DENIED_NOLOCKS;
      else
        rc = NLM4_GRANTED;

      goto out_put;
    }

  *ppowner = get_nlm_owner(care, *ppnlm_client, &alock->oh, alock->svid);

  if(*ppowner == NULL)
    {
      LogDebug(COMPONENT_NLM,
               "Could not get NLM Owner");
      dec_nsm_client_ref(*ppnsm_client);
      dec_nlm_client_ref(*ppnlm_client);
      *ppnlm_client = NULL;

      /* If owner is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      if(care != CARE_NOT)
        rc = NLM4_DENIED_NOLOCKS;
      else
        rc = NLM4_GRANTED;

      goto out_put;
    }

  if(ppblock_data != NULL)
    {
      *ppblock_data = gsh_calloc(1, sizeof(**ppblock_data));
      /* Fill in the block data, if we don't get one, we will just proceed
       * without (which will mean the lock doesn't block.
       */
      if(*ppblock_data != NULL)
        {
          if(copy_xprt_addr(&(*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_hostaddr, ptr_svc) == 0)
            {
              LogFullDebug(COMPONENT_NLM,
                           "copy_xprt_addr failed for Program %d, Version %d, Function %d",
                           (int)preq->rq_prog, (int)preq->rq_vers, (int)preq->rq_proc);
              gsh_free(*ppblock_data);
              *ppblock_data = NULL;
              rc = NLM4_FAILED;
              goto out_put;
            }
          (*ppblock_data)->sbd_granted_callback = nlm_granted_callback;
          (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh.n_bytes =
            (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh_buf;
          (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh.n_len = alock->fh.n_len;
          memcpy((*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh_buf,
                 alock->fh.n_bytes,
                 alock->fh.n_len);
          /* FSF TODO: Ultimately I think the following will go away, we won't need the context, just the export */
          /* Copy credentials from pcontext */
#ifdef _USE_HPSS
	  /** @todo : PhD: Think about removing hpsscred_t from FSAL */ 
          (*ppblock_data)->sbd_credential.user  =  pcontext->credential.hpss_usercred.Uid ;
          (*ppblock_data)->sbd_credential.group =  pcontext->credential.hpss_usercred.Gid ;
#else
          (*ppblock_data)->sbd_credential = pcontext->credential;

          /* Copy the alt groups list */
          if(pcontext->credential.nbgroups != 0)
            {
              (*ppblock_data)->sbd_credential.alt_groups =
                      gsh_malloc(sizeof(gid_t) * pcontext->credential.nbgroups);
              if((*ppblock_data)->sbd_credential.alt_groups == NULL)
                {
                  gsh_free(*ppblock_data);
                  *ppblock_data = NULL;
                  rc = NLM4_FAILED;
                  goto out_put;
                }
              memcpy((*ppblock_data)->sbd_credential.alt_groups,
                     pcontext->credential.alt_groups,
                     pcontext->credential.nbgroups);
            }
#endif
        }
    }
  /* Fill in plock */
  plock->lock_type   = exclusive ? FSAL_LOCK_W : FSAL_LOCK_R;
  plock->lock_start  = alock->l_offset;
  plock->lock_length = alock->l_len;

  LogFullDebug(COMPONENT_NLM,
               "Parameters Processed");

  return -1;

 out_put:

  cache_inode_put(*ppentry);
  *ppentry = NULL;
  return rc;
}
Example #12
0
int nlm4_Unlock(nfs_arg_t * parg /* IN     */ ,
                exportlist_t * pexport /* IN     */ ,
                fsal_op_context_t * pcontext /* IN     */ ,
                cache_inode_client_t * pclient /* INOUT  */ ,
                hash_table_t * ht /* INOUT  */ ,
                struct svc_req *preq /* IN     */ ,
                nfs_res_t * pres /* OUT    */ )
{
  int lck_cnt, lck_state;
  nlm4_unlockargs *arg;
  cache_entry_t *pentry;
  fsal_attrib_list_t attr;
  nlm_lock_entry_t *nlm_entry;
  cache_inode_status_t cache_status;
  cache_inode_fsal_data_t fsal_data;

  LogFullDebug(COMPONENT_NFSPROTO,
                    "REQUEST PROCESSING: Calling nlm4_Lock");

  if(in_nlm_grace_period())
    {
      pres->res_nlm4test.test_stat.stat = NLM4_DENIED_GRACE_PERIOD;
      return NFS_REQ_OK;
    }

  /* Convert file handle into a cache entry */
  arg = &parg->arg_nlm4_unlock;
  if(!nfs3_FhandleToFSAL((nfs_fh3 *) & (arg->alock.fh), &fsal_data.handle, pcontext))
    {
      /* handle is not valid */
      pres->res_nlm4.stat.stat = NLM4_STALE_FH;
      /*
       * Should we do a REQ_OK so that the client get
       * a response ? FIXME!!
       */
      return NFS_REQ_DROP;
    }
  /* Now get the cached inode attributes */
  fsal_data.cookie = DIR_START;
  if((pentry = cache_inode_get(&fsal_data, &attr, ht,
                               pclient, pcontext, &cache_status)) == NULL)
    {
      /* handle is not valid */
      pres->res_nlm4.stat.stat = NLM4_STALE_FH;
      return NFS_REQ_OK;
    }

  /*
   * nlm_find_lock_entry with state NLM4_GRANTED will search for lock
   * in both blocked and granted state. We can get an unlock request
   * even for a lock in blocked state because grant rpc response could
   * get dropped and the client can think that lock is granted but the
   * server still consider it locked.
   */
  nlm_entry = nlm_find_lock_entry(&(arg->alock), 0, NLM4_GRANTED);
  if(!nlm_entry)
    {
      pres->res_nlm4.stat.stat = NLM4_DENIED_NOLOCKS;
      return NFS_REQ_OK;
    }
  lck_state = nlm_lock_entry_get_state(nlm_entry);
  pres->res_nlm4.stat.stat = NLM4_GRANTED;
  lck_cnt = nlm_delete_lock_entry(&(arg->alock));
  nlm_unmonitor_host(arg->alock.caller_name);
  /*
   * Now check whether we have blocked locks.
   * if found grant them the lock
   */
  if(lck_state == NLM4_GRANTED)
    nlm_grant_blocked_locks(&(arg->alock.fh));
  nlm_lock_entry_dec_ref(nlm_entry);
  return NFS_REQ_OK;
}
Example #13
0
/**
 *
 * cache_inode_get: Gets an entry by using its fsdata as a key and caches it if needed.
 * 
 * Gets an entry by using its fsdata as a key and caches it if needed.
 * ASSUMPTION: DIR_CONT entries are always garbabbaged before their related DIR_BEGINNG 
 *
 * @param fsdata [IN] file system data
 * @param pattr [OUT] pointer to the attributes for the result. 
 * @param ht [IN] hash table used for the cache, unused in this call.
 * @param pclient [INOUT] ressource allocated by the client for the nfs management.
 * @param pcontext [IN] FSAL credentials 
 * @param pstatus [OUT] returned status.
 * 
 * @return the pointer to the entry is successfull, NULL otherwise.
 *
 */
cache_entry_t *cache_inode_get(cache_inode_fsal_data_t * pfsdata,
                               fsal_attrib_list_t * pattr,
                               hash_table_t * ht,
                               cache_inode_client_t * pclient,
                               fsal_op_context_t * pcontext,
                               cache_inode_status_t * pstatus)
{
  hash_buffer_t key, value;
  cache_entry_t *pentry = NULL;
  fsal_status_t fsal_status;
  cache_inode_create_arg_t create_arg;
  cache_inode_file_type_t type;
  int hrc = 0;
  fsal_attrib_list_t fsal_attributes;
  cache_inode_fsal_data_t *ppoolfsdata = NULL;

  /* Set the return default to CACHE_INODE_SUCCESS */
  *pstatus = CACHE_INODE_SUCCESS;

  /* stats */
  pclient->stat.nb_call_total += 1;
  pclient->stat.func_stats.nb_call[CACHE_INODE_GET] += 1;

  /* Turn the input to a hash key */
  if(cache_inode_fsaldata_2_key(&key, pfsdata, pclient))
    {
      *pstatus = CACHE_INODE_UNAPPROPRIATED_KEY;

      /* stats */
      pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_GET] += 1;

      ppoolfsdata = (cache_inode_fsal_data_t *) key.pdata;
      RELEASE_PREALLOC(ppoolfsdata, pclient->pool_key, next_alloc);

      return NULL;
    }

  switch (hrc = HashTable_Get(ht, &key, &value))
    {
    case HASHTABLE_SUCCESS:
      /* Entry exists in the cache and was found */
      pentry = (cache_entry_t *) value.pdata;

      /* return attributes additionally */
      cache_inode_get_attributes(pentry, pattr);

      break;

    case HASHTABLE_ERROR_NO_SUCH_KEY:
      /* Cache miss, allocate a new entry */

      /* If we ask for a dir cont (in this case pfsdata.cookie != FSAL_DIR_BEGINNING, we have 
       * a client who performs a readdir in the middle of a directory, when the direcctories
       * have been garbbage. we must search for the DIR_BEGIN related to this DIR_CONT */
      if(pfsdata->cookie != DIR_START)
        {
          /* added for sanity check */
          LogDebug(COMPONENT_CACHE_INODE_GC,
              "=======> Pb cache_inode_get: line %u pfsdata->cookie != DIR_START (=%u) on object whose type is %u",
               __LINE__, pfsdata->cookie,
               cache_inode_fsal_type_convert(fsal_attributes.type));

          pfsdata->cookie = DIR_START;

          /* Free this key */
          cache_inode_release_fsaldata_key(&key, pclient);

          /* redo the call */
          return cache_inode_get(pfsdata, pattr, ht, pclient, pcontext, pstatus);
        }

      /* First, call FSAL to know what the object is */
      fsal_attributes.asked_attributes = pclient->attrmask;
      fsal_status = FSAL_getattrs(&pfsdata->handle, pcontext, &fsal_attributes);
      if(FSAL_IS_ERROR(fsal_status))
        {
          *pstatus = cache_inode_error_convert(fsal_status);

          LogDebug(COMPONENT_CACHE_INODE_GC, "cache_inode_get: line %u cache_inode_status=%u fsal_status=%u,%u ",
                     __LINE__, *pstatus, fsal_status.major, fsal_status.minor);

          if(fsal_status.major == ERR_FSAL_STALE)
            {
              char handle_str[256];

              snprintHandle(handle_str, 256, &pfsdata->handle);
              LogEvent(COMPONENT_CACHE_INODE_GC,"cache_inode_get: Stale FSAL File Handle %s", handle_str);

              *pstatus = CACHE_INODE_FSAL_ESTALE;
            }

          /* stats */
          pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_GET] += 1;

          /* Free this key */
          cache_inode_release_fsaldata_key(&key, pclient);

          return NULL;
        }

      /* The type has to be set in the attributes */
      if(!FSAL_TEST_MASK(fsal_attributes.supported_attributes, FSAL_ATTR_TYPE))
        {
          *pstatus = CACHE_INODE_FSAL_ERROR;

          /* stats */
          pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_GET] += 1;

          /* Free this key */
          cache_inode_release_fsaldata_key(&key, pclient);

          return NULL;
        }

      /* Get the cache_inode file type */
      type = cache_inode_fsal_type_convert(fsal_attributes.type);

      if(type == SYMBOLIC_LINK)
        {
          FSAL_CLEAR_MASK(fsal_attributes.asked_attributes);
          FSAL_SET_MASK(fsal_attributes.asked_attributes, pclient->attrmask);
          fsal_status =
              FSAL_readlink(&pfsdata->handle, pcontext, &create_arg.link_content,
                            &fsal_attributes);
          if(FSAL_IS_ERROR(fsal_status))
            {
              *pstatus = cache_inode_error_convert(fsal_status);

              /* stats */
              pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_GET] += 1;

              /* Free this key */
              cache_inode_release_fsaldata_key(&key, pclient);

              if(fsal_status.major == ERR_FSAL_STALE)
                {
                  cache_inode_status_t kill_status;

                  LogDebug(COMPONENT_CACHE_INODE_GC,
                      "cache_inode_get: Stale FSAL File Handle detected for pentry = %p",
                       pentry);

                  if(cache_inode_kill_entry(pentry, ht, pclient, &kill_status) !=
                     CACHE_INODE_SUCCESS)
                    LogCrit(COMPONENT_CACHE_INODE_GC,"cache_inode_get: Could not kill entry %p, status = %u",
                               pentry, kill_status);

                  *pstatus = CACHE_INODE_FSAL_ESTALE;

                }

              return NULL;
            }
        }

      /* Add the entry to the cache */
      if((pentry = cache_inode_new_entry(pfsdata, &fsal_attributes, type, &create_arg, NULL,    /* never used to add a new DIR_CONTINUE within the scope of this function */
                                         ht, pclient, pcontext, FALSE,  /* This is a population, not a creation */
                                         pstatus)) == NULL)
        {
          /* stats */
          pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_GET] += 1;

          /* Free this key */
          cache_inode_release_fsaldata_key(&key, pclient);

          return NULL;
        }

      /* Set the returned attributes */
      *pattr = fsal_attributes;

      /* Now, exit the switch/case and returns */
      break;

    default:
      /* This should not happened */
      *pstatus = CACHE_INODE_INVALID_ARGUMENT;

      /* stats */
      pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_GET] += 1;

      /* Free this key */
      cache_inode_release_fsaldata_key(&key, pclient);

      return NULL;
      break;
    }

  *pstatus = CACHE_INODE_SUCCESS;

  /* valid the found entry, if this is not feasable, returns nothing to the client */
  P_w(&pentry->lock);
  if((*pstatus =
      cache_inode_valid(pentry, CACHE_INODE_OP_GET, pclient)) != CACHE_INODE_SUCCESS)
    {
      V_w(&pentry->lock);
      pentry = NULL;
    }
  V_w(&pentry->lock);

  /* stats */
  pclient->stat.func_stats.nb_success[CACHE_INODE_GET] += 1;

  /* Free this key */
  cache_inode_release_fsaldata_key(&key, pclient);

  return pentry;
}                               /* cache_inode_get */
Example #14
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 ;
}
Example #15
0
int nlm_process_parameters(struct svc_req        * preq,
                           bool_t                  exclusive,
                           nlm4_lock             * alock,
                           state_lock_desc_t     * plock,
                           hash_table_t          * ht,
                           cache_entry_t        ** ppentry,
                           fsal_op_context_t     * pcontext,
                           cache_inode_client_t  * pclient,
                           care_t                  care,
                           state_nsm_client_t   ** ppnsm_client,
                           state_nlm_client_t   ** ppnlm_client,
                           state_owner_t        ** ppowner,
                           state_block_data_t   ** ppblock_data)
{
  cache_inode_fsal_data_t fsal_data;
  fsal_attrib_list_t      attr;
  cache_inode_status_t    cache_status;
  SVCXPRT                *ptr_svc = preq->rq_xprt;

  *ppnsm_client = NULL;
  *ppnlm_client = NULL;
  *ppowner      = NULL;

  /* Convert file handle into a cache entry */
  if(alock->fh.n_len > MAX_NETOBJ_SZ ||
     !nfs3_FhandleToFSAL((nfs_fh3 *) &alock->fh, &fsal_data.handle, pcontext))
    {
      /* handle is not valid */
      return NLM4_STALE_FH;
    }

  /* Now get the cached inode attributes */
  fsal_data.cookie = DIR_START;
  *ppentry = cache_inode_get(&fsal_data,
                             CACHE_INODE_JOKER_POLICY,
                             &attr,
                             ht,
                             pclient,
                             pcontext,
                             &cache_status);
  if(*ppentry == NULL)
    {
      /* handle is not valid */
      return NLM4_STALE_FH;
    }

  *ppnsm_client = get_nsm_client(care, ptr_svc, alock->caller_name);

  if(*ppnsm_client == NULL)
    {
      /* If NSM Client is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      if(care != CARE_NOT)
        return NLM4_DENIED_NOLOCKS;
      else
        return NLM4_GRANTED;
    }

  *ppnlm_client = get_nlm_client(care, ptr_svc, *ppnsm_client, alock->caller_name);

  if(*ppnlm_client == NULL)
    {
      /* If NLM Client is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      dec_nsm_client_ref(*ppnsm_client);

      if(care != CARE_NOT)
        return NLM4_DENIED_NOLOCKS;
      else
        return NLM4_GRANTED;
    }

  *ppowner = get_nlm_owner(care, *ppnlm_client, &alock->oh, alock->svid);

  if(*ppowner == NULL)
    {
      LogDebug(COMPONENT_NLM,
               "Could not get NLM Owner");
      dec_nsm_client_ref(*ppnsm_client);
      dec_nlm_client_ref(*ppnlm_client);
      *ppnlm_client = NULL;

      /* If owner is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      if(care)
        return NLM4_DENIED_NOLOCKS;
      else
        return NLM4_GRANTED;
    }

  if(ppblock_data != NULL)
    {
      *ppblock_data = (state_block_data_t *) Mem_Alloc_Label(sizeof(**ppblock_data),
                                                             "NLM_Block_Data");
      /* Fill in the block data, if we don't get one, we will just proceed
       * without (which will mean the lock doesn't block.
       */
      if(*ppblock_data != NULL)
        {
          memset(*ppblock_data, 0, sizeof(**ppblock_data));
          if(copy_xprt_addr(&(*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_hostaddr, ptr_svc) == 0)
            {
              LogFullDebug(COMPONENT_NLM,
                           "copy_xprt_addr failed for Program %d, Version %d, Function %d",
                           (int)preq->rq_prog, (int)preq->rq_vers, (int)preq->rq_proc);
              Mem_Free(*ppblock_data);
              *ppblock_data = NULL;
              return NLM4_FAILED;
            }
          (*ppblock_data)->sbd_granted_callback = nlm_granted_callback;
          (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh.n_bytes =
            (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh_buf;
          (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh.n_len = alock->fh.n_len;
          memcpy((*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh_buf,
                 alock->fh.n_bytes,
                 alock->fh.n_len);
          /* FSF TODO: Ultimately I think the following will go away, we won't need the context, just the export */
          /* Copy credentials from pcontext */
          (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_credential = pcontext->credential;
        }
    }
  /* Fill in plock */
  plock->sld_type   = exclusive ? STATE_LOCK_W : STATE_LOCK_R;
  plock->sld_offset = alock->l_offset;
  plock->sld_length = alock->l_len;

  LogFullDebug(COMPONENT_NLM,
               "Parameters Processed");

  return -1;
}
/**
 *
 * cache_inode_lookupp_sw: looks up (and caches) the parent directory for a directory. A switches tells is mutex are use.
 * 
 * Looks up (and caches) the parent directory for a directory.
 *
 * @param pentry [IN] entry whose parent is to be obtained.
 * @param ht [IN] hash table used for the cache, unused in this call.
 * @param pclient [INOUT] ressource allocated by the client for the nfs management.
 * @param pcontext [IN] FSAL credentials 
 * @param pstatus [OUT] returned status.
 * @param use_mutex [IN] if TRUE mutex are use, not otherwise.
 * 
 * @return CACHE_INODE_SUCCESS if operation is a success \n
 * @return CACHE_INODE_LRU_ERROR if allocation error occured when validating the entry
 *
 */
cache_entry_t *cache_inode_lookupp_sw(cache_entry_t * pentry,
                                      hash_table_t * ht,
                                      cache_inode_client_t * pclient,
                                      fsal_op_context_t * pcontext,
                                      cache_inode_status_t * pstatus, int use_mutex)
{
  cache_entry_t *pentry_parent = NULL;
  fsal_status_t fsal_status;
  fsal_attrib_list_t object_attributes;
  cache_inode_fsal_data_t fsdata;

  /* Set the return default to CACHE_INODE_SUCCESS */
  *pstatus = CACHE_INODE_SUCCESS;

  /* stats */
  pclient->stat.nb_call_total += 1;
  pclient->stat.func_stats.nb_call[CACHE_INODE_LOOKUP] += 1;

  /* The entry should be a directory */
  if(use_mutex)
    P_r(&pentry->lock);
  if(pentry->internal_md.type != DIR_BEGINNING)
    {
      if(use_mutex)
        V_r(&pentry->lock);
      *pstatus = CACHE_INODE_BAD_TYPE;

      /* stats */
      pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_LOOKUPP] += 1;

      return NULL;
    }

  /* Renew the entry (to avoid having it being garbagged */
  if(cache_inode_renew_entry(pentry, NULL, ht, pclient, pcontext, pstatus) !=
     CACHE_INODE_SUCCESS)
    {
      pclient->stat.func_stats.nb_err_retryable[CACHE_INODE_GETATTR] += 1;
      return NULL;
    }

  /* Does the parent belongs to the cache ? */
  if(pentry->parent_list && pentry->parent_list->parent)
    {
      /* YES, the parent is cached, use the pentry that we have found */
      pentry_parent = pentry->parent_list->parent;
    }
  else
    {
      /* NO, the parent is not cached, query FSAL to get it and cache the result */
      object_attributes.asked_attributes = pclient->attrmask;
      fsal_status =
          FSAL_lookup(&pentry->object.dir_begin.handle, (fsal_name_t *) & FSAL_DOT_DOT,
                      pcontext, &fsdata.handle, &object_attributes);

      if(FSAL_IS_ERROR(fsal_status))
        {
          *pstatus = cache_inode_error_convert(fsal_status);
          if(use_mutex)
            V_r(&pentry->lock);

          /* Stale File Handle to be detected and managed */
          if(fsal_status.major == ERR_FSAL_STALE)
            {
              cache_inode_status_t kill_status;

              LogEvent(COMPONENT_CACHE_INODE,"cache_inode_lookupp: Stale FSAL FH detected for pentry %p",
                         pentry);

              if(cache_inode_kill_entry(pentry, ht, pclient, &kill_status) !=
                 CACHE_INODE_SUCCESS)
                LogCrit(COMPONENT_CACHE_INODE,"cache_inode_remove: Could not kill entry %p, status = %u",
                           pentry, kill_status);

              *pstatus = CACHE_INODE_FSAL_ESTALE;
            }

          /* stats */
          pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_LOOKUPP] += 1;

          return NULL;
        }

      /* Call cache_inode_get to populate the cache with the parent entry */
      fsdata.cookie = 0;

      if((pentry_parent = cache_inode_get(&fsdata,
                                          &object_attributes,
                                          ht, pclient, pcontext, pstatus)) == NULL)
        {
          if(use_mutex)
            V_r(&pentry->lock);

          /* stats */
          pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_LOOKUPP] += 1;

          return NULL;
        }
    }

  *pstatus = cache_inode_valid(pentry_parent, CACHE_INODE_OP_GET, pclient);
  if(use_mutex)
    V_r(&pentry->lock);

  /* stat */
  if(*pstatus != CACHE_INODE_SUCCESS)
    pclient->stat.func_stats.nb_err_retryable[CACHE_INODE_LOOKUPP] += 1;
  else
    pclient->stat.func_stats.nb_success[CACHE_INODE_LOOKUPP] += 1;

  return pentry_parent;
}                               /* cache_inode_lookupp_sw */
Example #17
0
/**
 *
 * cache_inode_readdir_nonamecache: Reads a directory without populating the name cache (no dirents created).
 *
 * Reads a directory without populating the name cache (no dirents created).
 *
 * @param pentry [IN] entry for the parent directory to be read.
 * @param cookie [IN] cookie for the readdir operation (basically the offset).
 * @param nbwanted [IN] Maximum number of directory entries wanted.
 * @param peod_met [OUT] A flag to know if end of directory was met during this call.
 * @param dirent_array [OUT] the resulting array of found directory entries.
 * @param ht [IN] hash table used for the cache, unused in this call.
 * @param unlock [OUT] the caller shall release read-lock on pentry when done
 * @param pclient [INOUT] ressource allocated by the client for the nfs management.
 * @param pcontext [IN] FSAL credentials
 * @param pstatus [OUT] returned status.
 *
 * @return CACHE_INODE_SUCCESS if operation is a success \n
 *
 */
static cache_inode_status_t cache_inode_readdir_nonamecache( cache_entry_t * pentry_dir,
                                                             cache_inode_policy_t policy,
                                                             uint64_t cookie,
                                                             unsigned int nbwanted,
                                                             unsigned int *pnbfound,
                                                             uint64_t *pend_cookie,
                                                             cache_inode_endofdir_t *peod_met,
                                                             cache_inode_dir_entry_t **dirent_array,
                                                             hash_table_t *ht,
                                                             int *unlock,
                                                             cache_inode_client_t *pclient,
                                                             fsal_op_context_t *pcontext,
                                                             cache_inode_status_t *pstatus)
{
  fsal_dir_t fsal_dirhandle;
  fsal_status_t fsal_status;
  fsal_attrib_list_t dir_attributes;

  fsal_cookie_t begin_cookie;
  fsal_cookie_t end_cookie;
  fsal_count_t iter;
  fsal_boolean_t fsal_eod;
  fsal_dirent_t fsal_dirent_array[FSAL_READDIR_SIZE + 20];

  cache_inode_fsal_data_t entry_fsdata;

  /* Set the return default to CACHE_INODE_SUCCESS */
  *pstatus = CACHE_INODE_SUCCESS;

  /* Only DIRECTORY entries are concerned */
  if(pentry_dir->internal_md.type != DIRECTORY)
    {
      *pstatus = CACHE_INODE_BAD_TYPE;
      return *pstatus;
    }

  LogFullDebug(COMPONENT_NFS_READDIR,
               "About to readdir in  cache_inode_readdir_nonamecache: pentry=%p "
	       "cookie=%"PRIu64, pentry_dir, cookie ) ;

  /* Open the directory */
  dir_attributes.asked_attributes = pclient->attrmask;
#ifdef _USE_MFSL
  fsal_status = MFSL_opendir(&pentry_dir->mobject,
                             pcontext,
                             &pclient->mfsl_context, &fsal_dirhandle, &dir_attributes, NULL);
#else
  fsal_status = FSAL_opendir(&pentry_dir->object.dir.handle,
                             pcontext, &fsal_dirhandle, &dir_attributes);
#endif

  if(FSAL_IS_ERROR(fsal_status))
    {
      *pstatus = cache_inode_error_convert(fsal_status);

      if(fsal_status.major == ERR_FSAL_STALE)
        {
          cache_inode_status_t kill_status;

          LogEvent(COMPONENT_CACHE_INODE,
                   "cache_inode_readdir: Stale FSAL File Handle detected for pentry = %p, fsal_status=(%u,%u)",
                   pentry_dir, fsal_status.major, fsal_status.minor);

          if(cache_inode_kill_entry(pentry_dir, WT_LOCK, ht, pclient, &kill_status) !=
             CACHE_INODE_SUCCESS)
            LogCrit(COMPONENT_CACHE_INODE,
                    "cache_inode_readdir: Could not kill entry %p, status = %u",
                    pentry_dir, kill_status);

          *pstatus = CACHE_INODE_FSAL_ESTALE;
        }
      return *pstatus;
    }

  /* Loop for readding the directory */
  // memcpy( &(begin_cookie.data), &cookie, sizeof( uint64_t ) ) ;
  FSAL_SET_COOKIE_BY_OFFSET( begin_cookie, cookie ) ;
  fsal_eod = FALSE;

#ifdef _USE_MFSL
  fsal_status = MFSL_readdir( &fsal_dirhandle,
                              begin_cookie,
                              pclient->attrmask,
                              nbwanted * sizeof(fsal_dirent_t),
                              fsal_dirent_array,
                              &end_cookie,
                              (fsal_count_t *)pnbfound, 
                              &fsal_eod, 
                              &pclient->mfsl_context, 
                              NULL);
#else
  fsal_status = FSAL_readdir( &fsal_dirhandle,
                              begin_cookie,
                              pclient->attrmask,
                              nbwanted * sizeof(fsal_dirent_t),
                              fsal_dirent_array,
                              &end_cookie, 
                              (fsal_count_t *)pnbfound, 
                              &fsal_eod);
#endif
  if(FSAL_IS_ERROR(fsal_status))
   {
      *pstatus = cache_inode_error_convert(fsal_status);
      return *pstatus;
   }

  for( iter = 0 ; iter < *pnbfound ; iter ++ )
   {
      /* cache_inode_readdir does not return . or .. */
      if(!FSAL_namecmp(&(fsal_dirent_array[iter].name), (fsal_name_t *) & FSAL_DOT) ||
         !FSAL_namecmp(&(fsal_dirent_array[iter].name), (fsal_name_t *) & FSAL_DOT_DOT))
              continue;

      /* Get the related pentry without populating the name cache (but eventually populating the attrs cache */
      entry_fsdata.handle = fsal_dirent_array[iter].handle;
      entry_fsdata.cookie = 0; /* XXX needed? */

      /* Allocate a dirent to be returned to the client */
      /** @todo Make sure this piece of memory once the data are used */
      GetFromPool( dirent_array[iter], &pclient->pool_dir_entry, cache_inode_dir_entry_t);
      if( dirent_array[iter] == NULL ) 
       {
         *pstatus = CACHE_INODE_MALLOC_ERROR;
         return *pstatus;
       }


      /* fills in the dirent_array */
      if( ( dirent_array[iter]->pentry= cache_inode_get( &entry_fsdata,
                                                         policy,
                                                         &fsal_dirent_array[iter].attributes,
                                                         ht,
                                                         pclient,
                                                         pcontext,
                                                         pstatus ) ) == NULL )
          return *pstatus ;

      fsal_status = FSAL_namecpy( &dirent_array[iter]->name, &fsal_dirent_array[iter].name ) ;
      if(FSAL_IS_ERROR(fsal_status))
       {
         *pstatus = cache_inode_error_convert(fsal_status);
         return *pstatus;
       }
  
      (void) FSAL_cookie_to_uint64( &fsal_dirent_array[iter].handle,
                                    pcontext, 
                                    &fsal_dirent_array[iter].cookie,
                                    &dirent_array[iter]->fsal_cookie);

       dirent_array[iter]->cookie = dirent_array[iter]->fsal_cookie ;

   } /* for( iter = 0 ; iter < nbfound ; iter ++ ) */

  if( fsal_eod == TRUE )
    *peod_met = END_OF_DIR ;
  else
    *peod_met = TO_BE_CONTINUED ;

  /* Do not forget to set returned end cookie */
  //memcpy( pend_cookie, &(end_cookie.data), sizeof( uint64_t ) ) ; 
  FSAL_SET_POFFSET_BY_COOKIE( end_cookie, pend_cookie ) ;

  LogFullDebug(COMPONENT_NFS_READDIR,
               "End of readdir in  cache_inode_readdir_nonamecache: pentry=%p "
	       "cookie=%"PRIu64, pentry_dir, *pend_cookie ) ;


  /* Close the directory */
#ifdef _USE_MFSL
  fsal_status = MFSL_closedir(&fsal_dirhandle, &pclient->mfsl_context, NULL);
#else
  fsal_status = FSAL_closedir(&fsal_dirhandle);
#endif
  if(FSAL_IS_ERROR(fsal_status))
    {
      *pstatus = cache_inode_error_convert(fsal_status);
      return *pstatus;
    }

  return CACHE_INODE_SUCCESS ;
} /* cache_inode_readdir_nomanecache */
Example #18
0
int nlm_process_share_parms(struct svc_req        * preq,
                            nlm4_share            * share,
                            cache_entry_t        ** ppentry,
                            fsal_op_context_t     * pcontext,
                            care_t                  care,
                            state_nsm_client_t   ** ppnsm_client,
                            state_nlm_client_t   ** ppnlm_client,
                            state_owner_t        ** ppowner)
{
  cache_inode_fsal_data_t fsal_data;
  fsal_attrib_list_t      attr;
  cache_inode_status_t    cache_status;
  SVCXPRT                *ptr_svc = preq->rq_xprt;
  int                     rc;

  *ppnsm_client = NULL;
  *ppnlm_client = NULL;
  *ppowner      = NULL;

  /* Convert file handle into a cache entry */
  if(share->fh.n_len > MAX_NETOBJ_SZ ||
     !nfs3_FhandleToFSAL((nfs_fh3 *) &share->fh, &fsal_data.fh_desc, pcontext))
    {
      /* handle is not valid */
      return NLM4_STALE_FH;
    }

  /* Now get the cached inode attributes */
  *ppentry = cache_inode_get(&fsal_data,
                             &attr,
                             pcontext,
                             NULL,
                             &cache_status);

  if(*ppentry == NULL)
    {
      /* handle is not valid */
      return NLM4_STALE_FH;
    }

  *ppnsm_client = get_nsm_client(care, ptr_svc, share->caller_name);

  if(*ppnsm_client == NULL)
    {
      /* If NSM Client is not found, and we don't care (for unshare),
       * just return GRANTED (the unshare must succeed, there can't be
       * any shares).
       */
      if(care != CARE_NOT)
        rc = NLM4_DENIED_NOLOCKS;
      else
        rc = NLM4_GRANTED;

      goto out_put;
    }

  *ppnlm_client = get_nlm_client(care, ptr_svc, *ppnsm_client, share->caller_name);

  if(*ppnlm_client == NULL)
    {
      /* If NLM Client is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      dec_nsm_client_ref(*ppnsm_client);

      if(care != CARE_NOT)
        rc = NLM4_DENIED_NOLOCKS;
      else
        rc = NLM4_GRANTED;

      goto out_put;
    }

  *ppowner = get_nlm_owner(care, *ppnlm_client, &share->oh, 0);

  if(*ppowner == NULL)
    {
      LogDebug(COMPONENT_NLM,
               "Could not get NLM Owner");
      dec_nsm_client_ref(*ppnsm_client);
      dec_nlm_client_ref(*ppnlm_client);
      *ppnlm_client = NULL;

      /* If owner is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      if(care != CARE_NOT)
        rc = NLM4_DENIED_NOLOCKS;
      else
        rc = NLM4_GRANTED;

      goto out_put;
    }

  LogFullDebug(COMPONENT_NLM,
               "Parameters Processed");

  return -1;

 out_put:

  cache_inode_put(*ppentry);
  *ppentry = NULL;
  return rc;
}
Example #19
0
int nfs3_Commit(nfs_arg_t * parg,
                exportlist_t * pexport,
                fsal_op_context_t * pcontext,
                cache_inode_client_t * pclient,
                hash_table_t * ht, struct svc_req *preq, nfs_res_t * pres)
{
  static char __attribute__ ((__unused__)) funcName[] = "nfs3_Access";

  cache_inode_status_t cache_status;
  cache_entry_t *pentry = NULL;
  cache_inode_fsal_data_t fsal_data;
  fsal_attrib_list_t pre_attr;
  fsal_attrib_list_t *ppre_attr;
  uint64_t typeofcommit;

  if(isDebug(COMPONENT_NFSPROTO))
    {
      char str[LEN_FH_STR];
      sprint_fhandle3(str, &(parg->arg_commit3.file));
      LogDebug(COMPONENT_NFSPROTO,
               "REQUEST PROCESSING: Calling nfs3_Commit handle: %s", str);
    }

  /* to avoid setting it on each error case */
  pres->res_commit3.COMMIT3res_u.resfail.file_wcc.before.attributes_follow = FALSE;
  pres->res_commit3.COMMIT3res_u.resfail.file_wcc.after.attributes_follow = FALSE;
  ppre_attr = NULL;

  /* Convert file handle into a fsal_handle */
  if(nfs3_FhandleToFSAL(&(parg->arg_commit3.file), &fsal_data.handle, pcontext) == 0)
    return NFS_REQ_DROP;

  /* Set cookie to 0 */
  fsal_data.cookie = DIR_START;

  /* Get the entry in the cache_inode */
  if((pentry = cache_inode_get( &fsal_data,
                                pexport->cache_inode_policy,
                                &pre_attr, 
                                ht, 
                                pclient, 
                                pcontext, 
                                &cache_status)) == NULL)
    {
      /* Stale NFS FH ? */
      pres->res_commit3.status = NFS3ERR_STALE;
      return NFS_REQ_OK;
    }

  if((pexport->use_commit == TRUE) &&
     (pexport->use_ganesha_write_buffer == FALSE))
    typeofcommit = FSAL_UNSAFE_WRITE_TO_FS_BUFFER;
  else if((pexport->use_commit == TRUE) &&
          (pexport->use_ganesha_write_buffer == TRUE))
    typeofcommit = FSAL_UNSAFE_WRITE_TO_GANESHA_BUFFER;
  else 
    /* We only do stable writes with this export so no need to execute a commit */
    return NFS_REQ_OK;    

  /* Do not use DC if data cache is enabled, the data is kept synchronous is the DC */
  if(cache_inode_commit(pentry,
                        parg->arg_commit3.offset,
                        parg->arg_commit3.count,
                        &pre_attr,
                        ht, pclient, pcontext, typeofcommit, &cache_status) != CACHE_INODE_SUCCESS)
    {
      pres->res_commit3.status = NFS3ERR_IO;;

      nfs_SetWccData(pcontext,
                     pexport,
                     pentry,
                     ppre_attr,
                     ppre_attr, &(pres->res_commit3.COMMIT3res_u.resfail.file_wcc));

      return NFS_REQ_OK;
    }

  /* Set the pre_attr */
  ppre_attr = &pre_attr;

  nfs_SetWccData(pcontext,
                 pexport,
                 pentry,
                 ppre_attr, ppre_attr, &(pres->res_commit3.COMMIT3res_u.resok.file_wcc));

  /* Set the write verifier */
  memcpy(pres->res_commit3.COMMIT3res_u.resok.verf, NFS3_write_verifier,
         sizeof(writeverf3));
  pres->res_commit3.status = NFS3_OK;

  return NFS_REQ_OK;
}                               /* nfs3_Commit */