Пример #1
0
int nfs4_op_putrootfh(struct nfs_argop4 *op,
                      compound_data_t * data, struct nfs_resop4 *resp)
{
  char __attribute__ ((__unused__)) funcname[] = "nfs4_op_putrootfh";

  /* This NFS4 Operation has no argument, it just get then ROOTFH (replace MOUNTPROC3_MNT) */

  /* First of all, set the reply to zero to make sure it contains no parasite information */
  memset(resp, 0, sizeof(struct nfs_resop4));
  resp->resop = NFS4_OP_PUTROOTFH;

  res_PUTROOTFH4.status = CreateROOTFH4(&(data->rootFH), data);
  if(res_PUTROOTFH4.status != NFS4_OK)
    return res_PUTROOTFH4.status;

  if (data->current_entry) {
      cache_inode_put(data->current_entry);
  }

  /* Fill in compound data */
  set_compound_data_for_pseudo(data);

  /* I copy the root FH to the currentFH */
  if(data->currentFH.nfs_fh4_len == 0)
    {
      res_PUTROOTFH4.status = nfs4_AllocateFH(&(data->currentFH));
      if(res_PUTROOTFH4.status != NFS4_OK)
        return res_PUTROOTFH4.status;
    }

  /* Copy the data from root FH to current FH */
  memcpy(data->currentFH.nfs_fh4_val, data->rootFH.nfs_fh4_val,
         data->rootFH.nfs_fh4_len);
  data->currentFH.nfs_fh4_len = data->rootFH.nfs_fh4_len;

  LogHandleNFS4("NFS4 PUTROOTFH ROOT    FH: ", &data->rootFH);
  LogHandleNFS4("NFS4 PUTROOTFH CURRENT FH: ", &data->currentFH);

  LogFullDebug(COMPONENT_NFS_V4,
                    "NFS4 PUTROOTFH: Ending on status %d",
                    res_PUTROOTFH4.status);

  return res_PUTROOTFH4.status;
}                               /* nfs4_op_putrootfh */
Пример #2
0
int CreatePUBFH4(nfs_fh4 * fh, compound_data_t * data)
{
  pseudofs_entry_t psfsentry;
  int status = 0;

  psfsentry = *(data->pseudofs->reverse_tab[0]);

  if((status = nfs4_AllocateFH(&(data->publicFH))) != NFS4_OK)
    return status;

  if(!nfs4_PseudoToFhandle(&(data->publicFH), &psfsentry))
    return NFS4ERR_BADHANDLE;

  LogHandleNFS4("CREATE PUB FH: ", &data->publicFH);

  return NFS4_OK;
}                               /* CreatePUBFH4 */
Пример #3
0
static int CreateROOTFH4(nfs_fh4 * fh, compound_data_t * data)
{
  pseudofs_entry_t psfsentry;
  int              status = 0;

  psfsentry = *(data->pseudofs->reverse_tab[0]);

  /* If rootFH already set, return success */
  if(data->rootFH.nfs_fh4_len != 0)
    return NFS4_OK;

  if((status = nfs4_AllocateFH(&(data->rootFH))) != NFS4_OK)
    return status;

  if(!nfs4_PseudoToFhandle(&(data->rootFH), &psfsentry))
    return NFS4ERR_BADHANDLE;

  LogHandleNFS4("CREATE ROOT FH: ", &data->rootFH);

  return NFS4_OK;
}                               /* CreateROOTFH4 */
Пример #4
0
int nfs4_op_lookup(struct nfs_argop4 *op, compound_data_t * data, struct nfs_resop4 *resp)
{
  fsal_name_t name;
  char strname[MAXNAMLEN];
#ifndef _NO_XATTRD
  char objname[MAXNAMLEN];
#endif
  unsigned int xattr_found = FALSE;
  cache_entry_t *dir_pentry = NULL;
  cache_entry_t *file_pentry = NULL;
  fsal_attrib_list_t attrlookup;
  cache_inode_status_t cache_status;

  fsal_handle_t *pfsal_handle = NULL;

  char __attribute__ ((__unused__)) funcname[] = "nfs4_op_lookup";

  resp->resop = NFS4_OP_LOOKUP;
  res_LOOKUP4.status = NFS4_OK;

  /* If there is no FH */
  if(nfs4_Is_Fh_Empty(&(data->currentFH)))
    {
      res_LOOKUP4.status = NFS4ERR_NOFILEHANDLE;
      return res_LOOKUP4.status;
    }

  /* If the filehandle is invalid */
  if(nfs4_Is_Fh_Invalid(&(data->currentFH)))
    {
      res_LOOKUP4.status = NFS4ERR_BADHANDLE;
      return res_LOOKUP4.status;
    }

  /* Tests if the Filehandle is expired (for volatile filehandle) */
  if(nfs4_Is_Fh_Expired(&(data->currentFH)))
    {
      res_LOOKUP4.status = NFS4ERR_FHEXPIRED;
      return res_LOOKUP4.status;
    }

  /* Check for empty name */
  if(op->nfs_argop4_u.oplookup.objname.utf8string_len == 0 ||
     op->nfs_argop4_u.oplookup.objname.utf8string_val == NULL)
    {
      res_LOOKUP4.status = NFS4ERR_INVAL;
      return res_LOOKUP4.status;
    }

  /* Check for name to long */
  if(op->nfs_argop4_u.oplookup.objname.utf8string_len > FSAL_MAX_NAME_LEN)
    {
      res_LOOKUP4.status = NFS4ERR_NAMETOOLONG;
      return res_LOOKUP4.status;
    }

  /* If Filehandle points to a pseudo fs entry, manage it via pseudofs specific functions */
  if(nfs4_Is_Fh_Pseudo(&(data->currentFH)))
    return nfs4_op_lookup_pseudo(op, data, resp);

#ifndef _NO_XATTRD
  /* If Filehandle points to a xattr object, manage it via the xattrs specific functions */
  if(nfs4_Is_Fh_Xattr(&(data->currentFH)))
    return nfs4_op_lookup_xattr(op, data, resp);
#endif

  /* UTF8 strings may not end with \0, but they carry their length */
  utf82str(strname, sizeof(strname), &arg_LOOKUP4.objname);

#ifndef _NO_XATTRD
  /* Is this a .xattr.d.<object> name ? */
  if(nfs_XattrD_Name(strname, objname))
    {
      strcpy(strname, objname);
      xattr_found = TRUE;
    }
#endif

  if((cache_status = cache_inode_error_convert(FSAL_str2name(strname,
                                                             MAXNAMLEN,
                                                             &name))) !=
     CACHE_INODE_SUCCESS)
    {
      res_LOOKUP4.status = nfs4_Errno(cache_status);
      return res_LOOKUP4.status;
    }

  /* No 'cd .' is allowed return NFS4ERR_BADNAME in this case */
  /* No 'cd .. is allowed, return EINVAL in this case. NFS4_OP_LOOKUPP should be use instead */
  if(!FSAL_namecmp(&name, (fsal_name_t *) & FSAL_DOT)
     || !FSAL_namecmp(&name, (fsal_name_t *) & FSAL_DOT_DOT))
    {
      res_LOOKUP4.status = NFS4ERR_BADNAME;
      return res_LOOKUP4.status;
    }

  /* Do the lookup in the HPSS Namespace */
  file_pentry = NULL;
  dir_pentry = data->current_entry;

  /* Sanity check: dir_pentry should be ACTUALLY a directory */
  if(dir_pentry->internal_md.type != DIR_BEGINNING
     && dir_pentry->internal_md.type != DIR_CONTINUE)
    {
      /* This is not a directory */
      if(dir_pentry->internal_md.type == SYMBOLIC_LINK)
        res_LOOKUP4.status = NFS4ERR_SYMLINK;
      else
        res_LOOKUP4.status = NFS4ERR_NOTDIR;

      /* Return failed status */
      return res_LOOKUP4.status;
    }

  /* BUGAZOMEU: Faire la gestion des cross junction traverse */
  if((file_pentry = cache_inode_lookup(dir_pentry,
                                       &name,
                                       &attrlookup,
                                       data->ht,
                                       data->pclient,
                                       data->pcontext, &cache_status)) != NULL)
    {
      /* Extract the fsal attributes from the cache inode pentry */
      pfsal_handle = cache_inode_get_fsal_handle(file_pentry, &cache_status);

      if(cache_status != CACHE_INODE_SUCCESS)
        {
          res_LOOKUP4.status = NFS4ERR_SERVERFAULT;
          return res_LOOKUP4.status;
        }

      /* Convert it to a file handle */
      if(!nfs4_FSALToFhandle(&data->currentFH, pfsal_handle, data))
        {
          res_LOOKUP4.status = NFS4ERR_SERVERFAULT;
          return res_LOOKUP4.status;
        }

      /* Copy this to the mounted on FH (if no junction is traversed */
      memcpy((char *)(data->mounted_on_FH.nfs_fh4_val),
             (char *)(data->currentFH.nfs_fh4_val), data->currentFH.nfs_fh4_len);
      data->mounted_on_FH.nfs_fh4_len = data->currentFH.nfs_fh4_len;

#if 0
      print_buff((char *)cache_inode_get_fsal_handle(file_pentry, &cache_status),
                 sizeof(fsal_handle_t));
      print_buff((char *)cache_inode_get_fsal_handle(dir_pentry, &cache_status),
                 sizeof(fsal_handle_t));
#endif
      if(isFullDebug(COMPONENT_NFS_V4))
        {
          LogFullDebug(COMPONENT_NFS_V4,
                       "----> nfs4_op_lookup: name=%s  dir_pentry=%p  looked up pentry=%p",
                       strname, dir_pentry, file_pentry);
          LogFullDebug(COMPONENT_NFS_V4,
                       "----> FSAL handle parent puis fils dans nfs4_op_lookup");
          print_buff(COMPONENT_NFS_V4,
                     (char *)cache_inode_get_fsal_handle(file_pentry, &cache_status),
                     sizeof(fsal_handle_t));
          print_buff(COMPONENT_NFS_V4,
                     (char *)cache_inode_get_fsal_handle(dir_pentry, &cache_status),
                     sizeof(fsal_handle_t));
        }
      LogHandleNFS4("NFS4 LOOKUP CURRENT FH: ", &data->currentFH);

      /* Keep the pointer within the compound data */
      data->current_entry = file_pentry;
      data->current_filetype = file_pentry->internal_md.type;

      /* Return successfully */
      res_LOOKUP4.status = NFS4_OK;

#ifndef _NO_XATTRD
      /* If this is a xattr ghost directory name, update the FH */
      if(xattr_found == TRUE)
        res_LOOKUP4.status = nfs4_fh_to_xattrfh(&(data->currentFH), &(data->currentFH));
#endif

      if((data->current_entry->internal_md.type == DIR_BEGINNING) &&
         (data->current_entry->object.dir_begin.referral != NULL))
        {
          if(!nfs4_Set_Fh_Referral(&(data->currentFH)))
            {
              res_LOOKUP4.status = NFS4ERR_SERVERFAULT;
              return res_LOOKUP4.status;
            }
        }

      return NFS4_OK;

    }

  /* If the part of the code is reached, then something wrong occured in the lookup process, status is not HPSS_E_NOERROR 
   * and contains the code for the error */

  res_LOOKUP4.status = nfs4_Errno(cache_status);

  return res_LOOKUP4.status;
}                               /* nfs4_op_lookup */
Пример #5
0
int nfs4_op_putrootfh(struct nfs_argop4 *op, compound_data_t *data,
		      struct nfs_resop4 *resp)
{
	fsal_status_t status = {0, 0};
	struct fsal_obj_handle *file_obj;

	PUTROOTFH4res * const res_PUTROOTFH4 = &resp->nfs_resop4_u.opputrootfh;

	/* First of all, set the reply to zero to make sure
	 * it contains no parasite information
	 */
	memset(resp, 0, sizeof(struct nfs_resop4));
	resp->resop = NFS4_OP_PUTROOTFH;

	/* Release any old export reference */
	if (op_ctx->ctx_export != NULL)
		put_gsh_export(op_ctx->ctx_export);

	op_ctx->ctx_export = NULL;
	op_ctx->fsal_export = NULL;

	/* Clear out current entry for now */
	set_current_entry(data, NULL);

	/* Get the root export of the Pseudo FS */
	op_ctx->ctx_export = get_gsh_export_by_pseudo("/", true);

	if (op_ctx->ctx_export == NULL) {
		LogCrit(COMPONENT_EXPORT,
			"Could not get export for Pseudo Root");

		res_PUTROOTFH4->status = NFS4ERR_NOENT;
		return res_PUTROOTFH4->status;
	}

	op_ctx->fsal_export = op_ctx->ctx_export->fsal_export;

	/* Build credentials */
	res_PUTROOTFH4->status = nfs4_export_check_access(data->req);

	/* Test for access error (export should not be visible). */
	if (res_PUTROOTFH4->status == NFS4ERR_ACCESS) {
		/* Client has no access at all */
		LogDebug(COMPONENT_EXPORT,
			 "Client doesn't have access to Pseudo Root");
		return res_PUTROOTFH4->status;
	}

	if (res_PUTROOTFH4->status != NFS4_OK) {
		LogMajor(COMPONENT_EXPORT,
			 "Failed to get FSAL credentials Pseudo Root");
		return res_PUTROOTFH4->status;
	}

	/* Get the Pesudo Root inode of the mounted on export */
	status = nfs_export_get_root_entry(op_ctx->ctx_export, &file_obj);
	if (FSAL_IS_ERROR(status)) {
		LogCrit(COMPONENT_EXPORT,
			"Could not get root inode for Pseudo Root");

		res_PUTROOTFH4->status = nfs4_Errno_status(status);
		return res_PUTROOTFH4->status;
	}

	LogMidDebug(COMPONENT_EXPORT,
		    "Root node %p", data->current_obj);

	set_current_entry(data, file_obj);

	/* Put our ref */
	file_obj->obj_ops.put_ref(file_obj);

	/* Convert it to a file handle */
	if (!nfs4_FSALToFhandle(data->currentFH.nfs_fh4_val == NULL,
				&data->currentFH,
				data->current_obj,
				op_ctx->ctx_export)) {
		LogCrit(COMPONENT_EXPORT,
			"Could not get handle for Pseudo Root");

		res_PUTROOTFH4->status = NFS4ERR_SERVERFAULT;
		return res_PUTROOTFH4->status;
	}

	LogHandleNFS4("NFS4 PUTROOTFH CURRENT FH: ", &data->currentFH);

	res_PUTROOTFH4->status = NFS4_OK;
	return res_PUTROOTFH4->status;
}				/* nfs4_op_putrootfh */
Пример #6
0
int nfs4_op_putrootfh(struct nfs_argop4 *op,
                      compound_data_t * data, struct nfs_resop4 *resp)
{
  int error;

  char __attribute__ ((__unused__)) funcname[] = "nfs4_op_putrootfh";

  /* This NFS4 Operation has no argument, it just get then ROOTFH (replace MOUNTPROC3_MNT) */

  /* First of all, set the reply to zero to make sure it contains no parasite information */
  memset(resp, 0, sizeof(struct nfs_resop4));

  resp->resop = NFS4_OP_PUTROOTFH;
  resp->nfs_resop4_u.opputrootfh.status = NFS4_OK;

  if((error = CreateROOTFH4(&(data->rootFH), data)) != NFS4_OK)
    {
      res_PUTROOTFH4.status = error;
      return res_PUTROOTFH4.status;
    }
  data->current_entry = NULL;   /* No cache inode entry for the directory within pseudo fs */
  data->current_filetype = DIRECTORY;      /* Only directory in the pseudo fs */

  /* I copy the root FH to the currentFH and, if not already done, to the publicFH */
  /* For the moment, I choose to have rootFH = publicFH */
  /* For initial mounted_on_FH, I'll use the rootFH, this will change at junction traversal */
  if(data->currentFH.nfs_fh4_len == 0)
    {
      if((error = nfs4_AllocateFH(&(data->currentFH))) != NFS4_OK)
        {
          resp->nfs_resop4_u.opputrootfh.status = error;
          return error;
        }
    }
  memcpy((char *)(data->currentFH.nfs_fh4_val), (char *)(data->rootFH.nfs_fh4_val),
         data->rootFH.nfs_fh4_len);
  data->currentFH.nfs_fh4_len = data->rootFH.nfs_fh4_len;

  if(data->mounted_on_FH.nfs_fh4_len == 0)
    {
      if((error = nfs4_AllocateFH(&(data->mounted_on_FH))) != NFS4_OK)
        {
          resp->nfs_resop4_u.opputrootfh.status = error;
          return error;
        }
    }
  memcpy((char *)(data->mounted_on_FH.nfs_fh4_val), (char *)(data->rootFH.nfs_fh4_val),
         data->rootFH.nfs_fh4_len);
  data->mounted_on_FH.nfs_fh4_len = data->rootFH.nfs_fh4_len;

  if(data->publicFH.nfs_fh4_len == 0)
    {
      if((error = nfs4_AllocateFH(&(data->publicFH))) != NFS4_OK)
        {
          resp->nfs_resop4_u.opputrootfh.status = error;
          return error;
        }
    }
  /* Copy the data where they are supposed to be */
  memcpy((char *)(data->publicFH.nfs_fh4_val), (char *)(data->rootFH.nfs_fh4_val),
         data->rootFH.nfs_fh4_len);
  data->publicFH.nfs_fh4_len = data->rootFH.nfs_fh4_len;

  LogHandleNFS4("NFS4 PUTROOTFH ROOT    FH: ", &data->rootFH);
  LogHandleNFS4("NFS4 PUTROOTFH CURRENT FH: ", &data->currentFH);

  LogFullDebug(COMPONENT_NFS_V4,
                    "NFS4 PUTROOTFH: Ending on status %d",
                    resp->nfs_resop4_u.opputrootfh.status);

  return resp->nfs_resop4_u.opputrootfh.status;
}                               /* nfs4_op_putrootfh */