Пример #1
0
/**
 * GPFSFSAL_getattrs:
 * Get attributes for the object specified by its filehandle.
 *
 * \param filehandle (input):
 *        The handle of the object to get parameters.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param object_attributes (mandatory input/output):
 *        The retrieved attributes for the object.
 *        As input, it defines the attributes that the caller
 *        wants to retrieve (by positioning flags into this structure)
 *        and the output is built considering this input
 *        (it fills the structure according to the flags it contains).
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t GPFSFSAL_getattrs(fsal_handle_t * p_filehandle,       /* IN */
                            fsal_op_context_t * p_context,      /* IN */
                            fsal_attrib_list_t * p_object_attributes    /* IN/OUT */
    )
{
  fsal_status_t st;
  gpfsfsal_xstat_t buffxstat;

#ifdef _USE_NFS4_ACL
  fsal_accessflags_t access_mask = 0;
#endif

  /* sanity checks.
   * note : object_attributes is mandatory in GPFSFSAL_getattrs.
   */
  if(!p_filehandle || !p_context || !p_object_attributes)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_getattrs);

  TakeTokenFSCall();
  st = fsal_get_xstat_by_handle(p_context,
                           p_filehandle,
                                &buffxstat);
  ReleaseTokenFSCall();

  if(FSAL_IS_ERROR(st))
    ReturnStatus(st, INDEX_FSAL_getattrs);

  /* convert attributes */
  st = gpfsfsal_xstat_2_fsal_attributes(&buffxstat, p_object_attributes);
  if(FSAL_IS_ERROR(st))
    {
      FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
      FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
      ReturnStatus(st, INDEX_FSAL_getattrs);
    }

#ifdef _USE_NFS4_ACL
  if(p_object_attributes->acl)
    {
      /* Check permission to get attributes and ACL. */
      access_mask = FSAL_MODE_MASK_SET(0) |  /* Dummy */
                    FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_READ_ATTR |
                                       FSAL_ACE_PERM_READ_ACL);
    
      st = fsal_internal_testAccess(p_context, access_mask, NULL, p_object_attributes);
      if(FSAL_IS_ERROR(st))
        ReturnStatus(st, INDEX_FSAL_getattrs);
    }
#endif

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_getattrs);

}
int main() {
  fsal_path_t path;
  int rc,fd,status, i, memsz, mempos, memval;
  fsal_op_context_t op_context;
  struct statfs stat_buf;
  gpfsfsal_export_context_t *p_export_context = calloc(0, sizeof(gpfsfsal_export_context_t));
  fsal_handle_t object_handle;
  fsal_handle_t object_handle_garbled;
  gpfsfsal_xstat_t buffstat;
  fsal_name_t file_name;
  unsigned char *handle_ptr;

  char *TESTDIR = "/ibm/gpfs0";
  char *TESTFILE = "invalid_getattrs_example";
  char *TESTFILE_PATH = "/ibm/gpfs0/invalid_getattrs_example";
  char *CREATETESTFILE = "mknod /ibm/gpfs0/invalid_getattrs_example u 1 1";
  char *REMOVETESTFILE = "ssh int001st001 rm -rf /ibm/gpfs0/invalid_getattrs_example";

  printf("Creating test file: %s\n", TESTFILE);
  system(CREATETESTFILE);

  strcpy(path.path, TESTDIR);
  path.len = strlen(TESTDIR);

  strcpy(file_name.name, TESTFILE);
  file_name.len = strlen(TESTFILE);

  fd = open(path.path, O_RDONLY | O_DIRECTORY);
  if(fd < 0) {
    printf("Couldn't open directory.\n");
    return 0;
  }
  p_export_context->mount_root_fd = fd;

  rc = statfs(path.path, &stat_buf);
  if(rc) {
    printf ("statfs call failed on file %s: %d", path.path, rc);
    return 0;
  }
  
 p_export_context->fsid[0] = stat_buf.f_fsid.__val[0];
 p_export_context->fsid[1] = stat_buf.f_fsid.__val[1];
 
 /* Get file handle to root of GPFS share */
 op_context.export_context = p_export_context;

 status = fsal_internal_get_handle(&op_context,
				   &path,
				   (fsal_handle_t *)(&(p_export_context->mount_root_handle)));
 if (status)
   printf("fsal_internal_get_handle() failed\n");

 /* Now show the error for when we use a nonsense file handle. */
 /* printf("USING AN UNINITIALIZED FILE HANDLE FOR GETATTR ...\n");
 fsal_get_xstat_by_handle(&op_context, &object_handle, &buffstat);
 printf("\n");
 */
 /* Get handle of file */
 fsal_internal_get_handle_at(fd, &file_name, &object_handle);

 /* Getattrs of file */
 printf("USING A CORRECT FILE HANDLE FOR GETATTR ...\n");
 handle_ptr = ((gpfsfsal_handle_t *)&object_handle)->data.handle.f_handle;
 printf("handle: ");
 for(i=0; i < OPENHANDLE_HANDLE_LEN; i++)
   printf("%02x", (unsigned char)handle_ptr[i]);
 printf("\n");

 fsal_get_xstat_by_handle(&op_context, &object_handle, &buffstat);

 /* print attrs */
 print_attrs(&buffstat);
 printf("\n");

 /* Getattrs of file */
 /*
 printf("USING A FILE HANDLE THAT HAS BEEN MEMSET at 4th BYTE FOR GETATTR ...\n");
 memcpy(&object_handle_garbled, &object_handle, sizeof(fsal_handle_t));
 handle_ptr = ((gpfsfsal_handle_t *)&object_handle_garbled)->data.handle.f_handle;
 memset(handle_ptr+3, 4, 1); 

 printf("handle: ");
 for(i=0; i < OPENHANDLE_HANDLE_LEN; i++)
   printf("%02x", (unsigned char)handle_ptr[i]);
 printf("\n");

 fsal_get_xstat_by_handle(&op_context, &object_handle_garbled, &buffstat);
 printf("\n");
 */
 /* Getattrs of file */
 /*
 printf("USING A FILE HANDLE THAT HAS BEEN MEMSET at 2nd BYTE FOR GETATTR ...\n");
 memcpy(&object_handle_garbled, &object_handle, sizeof(fsal_handle_t));
 handle_ptr = ((gpfsfsal_handle_t *)&object_handle_garbled)->data.handle.f_handle;
 memset(handle_ptr+1, 4, 1); 

 printf("handle: ");
 for(i=0; i < OPENHANDLE_HANDLE_LEN; i++)
   printf("%02x", (unsigned char)handle_ptr[i]);
 printf("\n");

 fsal_get_xstat_by_handle(&op_context, &object_handle_garbled, &buffstat);
 printf("\n");
 */
 /* Getattrs of file */
 /*
 printf("USING FILE HANDLEs THAT HAVE BEEN MEMSET\n");
 for(memsz=0; memsz <= OPENHANDLE_HANDLE_LEN; memsz++) {
   for(mempos=0; mempos <= OPENHANDLE_HANDLE_LEN-memsz; mempos++) {
     for(memval=0; memval <= 255; memval++) {
       memcpy(&object_handle_garbled, &object_handle, sizeof(fsal_handle_t));
       handle_ptr = ((gpfsfsal_handle_t *)&object_handle_garbled)->data.handle.f_handle;
       memset(handle_ptr+mempos, memval, memsz); 
       
       printf("handle: ");
       for(i=0; i < OPENHANDLE_HANDLE_LEN; i++)
         printf("%02x", (unsigned char)handle_ptr[i]);
       printf("\n");
       
       fsal_get_xstat_by_handle(&op_context, &object_handle_garbled, &buffstat);
     }
   }
 }
 */
 /* delete file */
 printf("Removing test file: %s\n", TESTFILE);
 system(REMOVETESTFILE);

 /* Now show the INTERRUPT error. */
 printf("USING A FILE HANDLE FROM A DELETED FILE FOR GETATTR ...\n");
 fsal_get_xstat_by_handle(&op_context, &object_handle, &buffstat);
 printf("\n");

 close(fd);

 return 0;
}
Пример #3
0
/**
 *  @param exp_hdl Handle
 *  @param path Path
 *  @param handle Reference to handle
 *
 *  modelled on old api except we don't stuff attributes.
 *  @return Status of operation
 */
fsal_status_t gpfs_lookup_path(struct fsal_export *exp_hdl,
			       const char *path,
			       struct fsal_obj_handle **handle,
			       struct attrlist *attrs_out)
{
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	fsal_status_t fsal_status;
	int retval = 0;
	int dir_fd;
	struct fsal_filesystem *fs;
	struct gpfs_fsal_obj_handle *hdl;
	struct attrlist attributes;
	gpfsfsal_xstat_t buffxstat;
	struct gpfs_file_handle *fh = alloca(sizeof(struct gpfs_file_handle));
	struct fsal_fsid__ fsid;
	struct gpfs_fsal_export *gpfs_export;

	memset(fh, 0, sizeof(struct gpfs_file_handle));
	fh->handle_size = GPFS_MAX_FH_SIZE;

	*handle = NULL;	/* poison it */

	dir_fd = open_dir_by_path_walk(-1, path, &buffxstat.buffstat);

	fsal_prepare_attrs(&attributes, ATTR_GPFS_ALLOC_HANDLE);

	if (attrs_out != NULL)
		attributes.mask |= attrs_out->mask;

	if (dir_fd < 0) {
		LogCrit(COMPONENT_FSAL,
			"Could not open directory for path %s",
			path);
		retval = -dir_fd;
		goto errout;
	}

	fsal_status = fsal_internal_fd2handle(dir_fd, fh);
	if (FSAL_IS_ERROR(fsal_status))
		goto fileerr;

	gpfs_export = container_of(exp_hdl, struct gpfs_fsal_export, export);

	fsal_status = fsal_get_xstat_by_handle(dir_fd, fh, &buffxstat,
					       NULL, false,
					       (attributes.mask & ATTR_ACL)
									!= 0);
	if (FSAL_IS_ERROR(fsal_status))
		goto fileerr;
	fsal_status = gpfsfsal_xstat_2_fsal_attributes(&buffxstat, &attributes,
						       gpfs_export->use_acl);
	LogFullDebug(COMPONENT_FSAL,
		     "fsid=0x%016"PRIx64".0x%016"PRIx64,
		     attributes.fsid.major,
		     attributes.fsid.minor);
	if (FSAL_IS_ERROR(fsal_status))
		goto fileerr;

	close(dir_fd);

	gpfs_extract_fsid(fh, &fsid);

	fs = lookup_fsid(&fsid, GPFS_FSID_TYPE);

	if (fs == NULL) {
		LogInfo(COMPONENT_FSAL,
			"Could not find file system for path %s",
			path);
		retval = ENOENT;
		goto errout;
	}

	if (fs->fsal != exp_hdl->fsal) {
		LogInfo(COMPONENT_FSAL,
			"File system for path %s did not belong to FSAL %s",
			path, exp_hdl->fsal->name);
		retval = EACCES;
		goto errout;
	}

	LogDebug(COMPONENT_FSAL,
		 "filesystem %s for path %s",
		 fs->path, path);

	/* Make sure ATTR_RDATTR_ERR is cleared on success. */
	attributes.mask &= ~ATTR_RDATTR_ERR;

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(fh, fs, &attributes, NULL, exp_hdl);

	if (attrs_out != NULL) {
		/* Copy the attributes to caller, passing ACL ref. */
		fsal_copy_attrs(attrs_out, &attributes, true);
	} else {
		/* Done with the attrs */
		fsal_release_attrs(&attributes);
	}

	*handle = &hdl->obj_handle;
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 fileerr:
	retval = errno;
	close(dir_fd);

 errout:

	/* Done with attributes */
	fsal_release_attrs(&attributes);

	fsal_error = posix2fsal_error(retval);
	return fsalstat(fsal_error, retval);
}