Ejemplo n.º 1
0
void posix2fsal_attributes(const struct stat *buffstat,
			   struct attrlist *fsalattr)
{
	FSAL_CLEAR_MASK(fsalattr->mask);

	/* Fills the output struct */
	fsalattr->type = posix2fsal_type(buffstat->st_mode);
	FSAL_SET_MASK(fsalattr->mask, ATTR_TYPE);

	fsalattr->filesize = buffstat->st_size;
	FSAL_SET_MASK(fsalattr->mask, ATTR_SIZE);

	fsalattr->fsid = posix2fsal_fsid(buffstat->st_dev);
	FSAL_SET_MASK(fsalattr->mask, ATTR_FSID);

	fsalattr->fileid = buffstat->st_ino;
	FSAL_SET_MASK(fsalattr->mask, ATTR_FILEID);

	fsalattr->mode = unix2fsal_mode(buffstat->st_mode);
	FSAL_SET_MASK(fsalattr->mask, ATTR_MODE);

	fsalattr->numlinks = buffstat->st_nlink;
	FSAL_SET_MASK(fsalattr->mask, ATTR_NUMLINKS);

	fsalattr->owner = buffstat->st_uid;
	FSAL_SET_MASK(fsalattr->mask, ATTR_OWNER);

	fsalattr->group = buffstat->st_gid;
	FSAL_SET_MASK(fsalattr->mask, ATTR_GROUP);

	/* Use full timer resolution */
#ifdef LINUX
	fsalattr->atime = buffstat->st_atim;
	fsalattr->ctime = buffstat->st_ctim;
	fsalattr->mtime = buffstat->st_mtim;
	fsalattr->chgtime =
	    (gsh_time_cmp(&buffstat->st_mtim, &buffstat->st_ctim) >
	     0) ? fsalattr->mtime : fsalattr->ctime;
#elif FREEBSD
	fsalattr->atime = buffstat->st_atimespec;
	fsalattr->ctime = buffstat->st_ctimespec;
	fsalattr->mtime = buffstat->st_mtimespec;
	fsalattr->chgtime =
	    (gsh_time_cmp(&buffstat->st_mtimespec, &buffstat->st_ctimespec) >
	     0) ? fsalattr->mtime : fsalattr->ctime;
#endif
	FSAL_SET_MASK(fsalattr->mask, ATTR_ATIME);
	FSAL_SET_MASK(fsalattr->mask, ATTR_CTIME);
	FSAL_SET_MASK(fsalattr->mask, ATTR_MTIME);

	fsalattr->change = timespec_to_nsecs(&fsalattr->chgtime);
	FSAL_SET_MASK(fsalattr->mask, ATTR_CHGTIME);

	fsalattr->spaceused = buffstat->st_blocks * S_BLKSIZE;
	FSAL_SET_MASK(fsalattr->mask, ATTR_SPACEUSED);

	fsalattr->rawdev = posix2fsal_devt(buffstat->st_rdev);
	FSAL_SET_MASK(fsalattr->mask, ATTR_RAWDEV);
}
Ejemplo n.º 2
0
fsal_status_t posix2fsal_attributes(const struct stat *buffstat,
                                    struct attrlist *fsalattr)
{
  FSAL_CLEAR_MASK(fsalattr->mask);
  /* sanity checks */
  if(!buffstat || !fsalattr)
    return fsalstat(ERR_FSAL_FAULT, 0);

  FSAL_CLEAR_MASK(fsalattr->mask);

  /* Fills the output struct */
  fsalattr->type = posix2fsal_type(buffstat->st_mode);
  FSAL_SET_MASK(fsalattr->mask, ATTR_TYPE);

  fsalattr->filesize = buffstat->st_size;
  FSAL_SET_MASK(fsalattr->mask, ATTR_SIZE);

  fsalattr->fsid = posix2fsal_fsid(buffstat->st_dev);
  FSAL_SET_MASK(fsalattr->mask, ATTR_FSID);

  fsalattr->fileid = buffstat->st_ino;
  FSAL_SET_MASK(fsalattr->mask, ATTR_FILEID);

  fsalattr->mode = unix2fsal_mode(buffstat->st_mode);
  FSAL_SET_MASK(fsalattr->mask, ATTR_MODE);

  fsalattr->numlinks = buffstat->st_nlink;
  FSAL_SET_MASK(fsalattr->mask, ATTR_NUMLINKS);

  fsalattr->owner = buffstat->st_uid;
  FSAL_SET_MASK(fsalattr->mask, ATTR_OWNER);

  fsalattr->group = buffstat->st_gid;
  FSAL_SET_MASK(fsalattr->mask, ATTR_GROUP);

  fsalattr->atime = posix2fsal_time(buffstat->st_atime, 0);
  FSAL_SET_MASK(fsalattr->mask, ATTR_ATIME);

  fsalattr->ctime = posix2fsal_time(buffstat->st_ctime, 0);
  FSAL_SET_MASK(fsalattr->mask, ATTR_CTIME);

  fsalattr->mtime = posix2fsal_time(buffstat->st_mtime, 0);
  FSAL_SET_MASK(fsalattr->mask, ATTR_MTIME);

  fsalattr->chgtime
    = posix2fsal_time(MAX_2(buffstat->st_mtime,
                            buffstat->st_ctime), 0);
  fsalattr->change = fsalattr->chgtime.tv_sec;
  FSAL_SET_MASK(fsalattr->mask, ATTR_CHGTIME);

  fsalattr->spaceused = buffstat->st_blocks * S_BLKSIZE;
  FSAL_SET_MASK(fsalattr->mask, ATTR_SPACEUSED);

  fsalattr->rawdev = posix2fsal_devt(buffstat->st_rdev);
  FSAL_SET_MASK(fsalattr->mask, ATTR_RAWDEV);

  return fsalstat(ERR_FSAL_NO_ERROR, 0);
}
Ejemplo n.º 3
0
/* helpers
 */
int lustre_extract_fsid(struct lustre_file_handle *fh,
			enum fsid_type *fsid_type,
			struct fsal_fsid__ *fsid)
{
	struct fsal_dev__ dev;

	dev = posix2fsal_devt(fh->fsdev);

	*fsid_type = FSID_TWO_UINT64;
	fsid->major = dev.major;
	fsid->minor = dev.minor;
	return 0;
}
Ejemplo n.º 4
0
void stat2fsal_attributes(const struct stat *buffstat,
			  struct attrlist *fsalattr)
{
	/* Indicate which atrributes we have set without affecting the
	 * other bits in the mask.
	 */
	fsalattr->valid_mask |= ATTRS_POSIX;
	fsalattr->supported = op_ctx->fsal_export->exp_ops.fs_supported_attrs(
							op_ctx->fsal_export);

	/* Fills the output struct */
	fsalattr->type = posix2fsal_type(buffstat->st_mode);

	fsalattr->filesize = buffstat->st_size;

	fsalattr->fsid = posix2fsal_fsid(buffstat->st_dev);

	fsalattr->fileid = buffstat->st_ino;

	fsalattr->mode = unix2fsal_mode(buffstat->st_mode);

	fsalattr->numlinks = buffstat->st_nlink;

	fsalattr->owner = buffstat->st_uid;

	fsalattr->group = buffstat->st_gid;

	/** @todo: gfapi currently only fills in the legacy time_t fields
	 *         when it supports the timespec fields calls to this
	 *         function should be replaced with calls to
	 *         posix2fsal_attributes rather than changing this code.
	 */
	fsalattr->atime = posix2fsal_time(buffstat->st_atime, 0);
	fsalattr->ctime = posix2fsal_time(buffstat->st_ctime, 0);
	fsalattr->mtime = posix2fsal_time(buffstat->st_mtime, 0);

	fsalattr->chgtime = posix2fsal_time(MAX(buffstat->st_mtime,
						buffstat->st_ctime), 0);
	fsalattr->change = fsalattr->chgtime.tv_sec;

	fsalattr->spaceused = buffstat->st_blocks * S_BLKSIZE;

	fsalattr->rawdev = posix2fsal_devt(buffstat->st_rdev);
}
Ejemplo n.º 5
0
fsal_status_t posix2fsal_attributes(struct stat * p_buffstat,
                                    fsal_attrib_list_t * p_fsalattr_out)
{

  fsal_attrib_mask_t supp_attr, unsupp_attr;

  /* sanity checks */
  if(!p_buffstat || !p_fsalattr_out)
    ReturnCode(ERR_FSAL_FAULT, 0);

  /* check that asked attributes are supported */
  supp_attr = global_fs_info.supported_attrs;

  unsupp_attr = (p_fsalattr_out->asked_attributes) & (~supp_attr);
  if(unsupp_attr)
    {
      LogFullDebug(COMPONENT_FSAL, "Unsupported attributes: %#llX",
                        unsupp_attr);
      ReturnCode(ERR_FSAL_ATTRNOTSUPP, 0);
    }

  /* Initialize ACL regardless of whether ACL was asked or not.
   * This is needed to make sure ACL attribute is initialized. */
  p_fsalattr_out->acl = NULL;

  /* Fills the output struct */
  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_SUPPATTR))
    {
      p_fsalattr_out->supported_attributes = supp_attr;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_TYPE))
    {
      p_fsalattr_out->type = posix2fsal_type(p_buffstat->st_mode);
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_SIZE))
    {
      p_fsalattr_out->filesize = p_buffstat->st_size;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_FSID))
    {
      p_fsalattr_out->fsid = posix2fsal_fsid(p_buffstat->st_dev);
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_ACL))
    {
      p_fsalattr_out->acl = NULL;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_FILEID))
    {
      p_fsalattr_out->fileid = (fsal_u64_t) (p_buffstat->st_ino);
    }

  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_MODE))
    {
      p_fsalattr_out->mode = unix2fsal_mode(p_buffstat->st_mode);
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_NUMLINKS))
    {
      p_fsalattr_out->numlinks = p_buffstat->st_nlink;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_OWNER))
    {
      p_fsalattr_out->owner = p_buffstat->st_uid;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_GROUP))
    {
      p_fsalattr_out->group = p_buffstat->st_gid;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_ATIME))
    {
      p_fsalattr_out->atime = posix2fsal_time(p_buffstat->st_atime);

    }

  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_CTIME))
    {
      p_fsalattr_out->ctime = posix2fsal_time(p_buffstat->st_ctime);
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_MTIME))
    {
      p_fsalattr_out->mtime = posix2fsal_time(p_buffstat->st_mtime);
    }

  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_CHGTIME))
    {
      p_fsalattr_out->chgtime
          = posix2fsal_time(MAX_2(p_buffstat->st_mtime, p_buffstat->st_ctime));
      p_fsalattr_out->change = (uint64_t) p_fsalattr_out->chgtime.seconds ;
    }

  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_SPACEUSED))
    {
      p_fsalattr_out->spaceused = p_buffstat->st_blocks * S_BLKSIZE;
    }

  if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_RAWDEV))
    {
      p_fsalattr_out->rawdev = posix2fsal_devt(p_buffstat->st_rdev);    /* XXX: convert ? */
    }
  /* mounted_on_fileid :
     if ( FSAL_TEST_MASK(p_fsalattr_out->asked_attributes,
     FSAL_ATTR_MOUNTFILEID )){
     p_fsalattr_out->mounted_on_fileid = 
     hpss2fsal_64( p_hpss_attr_in->FilesetRootId );
     }
   */

  /* everything has been copied ! */

  ReturnCode(ERR_FSAL_NO_ERROR, 0);
}
Ejemplo n.º 6
0
/* Same function as posixstat64_2_fsal_attributes. When NFS4 ACL support
 * is enabled, this will replace posixstat64_2_fsal_attributes. */
fsal_status_t gpfsfsal_xstat_2_fsal_attributes(gpfsfsal_xstat_t *p_buffxstat,
					       struct attrlist *p_fsalattr_out,
					       bool use_acl)
{
	struct stat *p_buffstat;

	/* sanity checks */
	if (!p_buffxstat || !p_fsalattr_out)
		return fsalstat(ERR_FSAL_FAULT, 0);

	p_buffstat = &p_buffxstat->buffstat;

	LogDebug(COMPONENT_FSAL, "inode %ld", p_buffstat->st_ino);

	/* Fills the output struct */
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_TYPE)) {
		p_fsalattr_out->type = posix2fsal_type(p_buffstat->st_mode);
		LogFullDebug(COMPONENT_FSAL, "type = 0x%x",
			     p_fsalattr_out->type);
	}
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_SIZE)) {
		p_fsalattr_out->filesize = p_buffstat->st_size;
		LogFullDebug(COMPONENT_FSAL, "filesize = %llu",
			     (unsigned long long)p_fsalattr_out->filesize);
	}
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_FSID)) {
		p_fsalattr_out->fsid = p_buffxstat->fsal_fsid;
		LogFullDebug(COMPONENT_FSAL,
			     "fsid=0x%016"PRIx64".0x%016"PRIx64,
			     p_fsalattr_out->fsid.major,
			     p_fsalattr_out->fsid.minor);
	}
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_ACL)) {
		p_fsalattr_out->acl = NULL;
		if (use_acl && p_buffxstat->attr_valid & XATTR_ACL) {
			/* ACL is valid, so try to convert fsal acl. */
			gpfs_acl_2_fsal_acl(p_fsalattr_out,
					    (gpfs_acl_t *) p_buffxstat->
					    buffacl);
		}
		LogFullDebug(COMPONENT_FSAL, "acl = %p", p_fsalattr_out->acl);
	}
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_FILEID)) {
		p_fsalattr_out->fileid = (uint64_t) (p_buffstat->st_ino);
		LogFullDebug(COMPONENT_FSAL, "fileid = %lu",
			     p_fsalattr_out->fileid);
	}

	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_MODE)) {
		p_fsalattr_out->mode = unix2fsal_mode(p_buffstat->st_mode);
		LogFullDebug(COMPONENT_FSAL, "mode = %"PRIu32,
			     p_fsalattr_out->mode);
	}
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_NUMLINKS)) {
		p_fsalattr_out->numlinks = p_buffstat->st_nlink;
		LogFullDebug(COMPONENT_FSAL, "numlinks = %u",
			     p_fsalattr_out->numlinks);
	}
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_OWNER)) {
		p_fsalattr_out->owner = p_buffstat->st_uid;
		LogFullDebug(COMPONENT_FSAL, "owner = %lu",
			     p_fsalattr_out->owner);
	}
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_GROUP)) {
		p_fsalattr_out->group = p_buffstat->st_gid;
		LogFullDebug(COMPONENT_FSAL, "group = %lu",
			     p_fsalattr_out->group);
	}
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_ATIME)) {
		p_fsalattr_out->atime =
		    posix2fsal_time(p_buffstat->st_atime,
				    p_buffstat->st_atim.tv_nsec);
		LogFullDebug(COMPONENT_FSAL, "atime = %lu",
			     p_fsalattr_out->atime.tv_sec);
	}

	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_CTIME)) {
		p_fsalattr_out->ctime =
		    posix2fsal_time(p_buffstat->st_ctime,
				    p_buffstat->st_ctim.tv_nsec);
		LogFullDebug(COMPONENT_FSAL, "ctime = %lu",
			     p_fsalattr_out->ctime.tv_sec);
	}
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_MTIME)) {
		p_fsalattr_out->mtime =
		    posix2fsal_time(p_buffstat->st_mtime,
				    p_buffstat->st_mtim.tv_nsec);
		LogFullDebug(COMPONENT_FSAL, "mtime = %lu",
			     p_fsalattr_out->mtime.tv_sec);
	}

	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_CHGTIME)) {
		if (p_buffstat->st_mtime == p_buffstat->st_ctime) {
			if (p_buffstat->st_mtim.tv_nsec >
			    p_buffstat->st_ctim.tv_nsec)
				p_fsalattr_out->chgtime =
				    posix2fsal_time(p_buffstat->st_mtime,
						    p_buffstat->st_mtim.
						    tv_nsec);
			else
				p_fsalattr_out->chgtime =
				    posix2fsal_time(p_buffstat->st_ctime,
						    p_buffstat->st_ctim.
						    tv_nsec);
		} else if (p_buffstat->st_mtime > p_buffstat->st_ctime) {
			p_fsalattr_out->chgtime =
			    posix2fsal_time(p_buffstat->st_mtime,
					    p_buffstat->st_mtim.tv_nsec);
		} else {
			p_fsalattr_out->chgtime =
			    posix2fsal_time(p_buffstat->st_ctime,
					    p_buffstat->st_ctim.tv_nsec);
		}
		p_fsalattr_out->change =
		    (uint64_t) p_fsalattr_out->chgtime.tv_sec +
		    (uint64_t) p_fsalattr_out->chgtime.tv_nsec;
		LogFullDebug(COMPONENT_FSAL, "chgtime = %lu",
			     p_fsalattr_out->chgtime.tv_sec);

	}

	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_SPACEUSED)) {
		p_fsalattr_out->spaceused = p_buffstat->st_blocks * S_BLKSIZE;
		LogFullDebug(COMPONENT_FSAL, "spaceused = %llu",
			     (unsigned long long)p_fsalattr_out->spaceused);
	}

	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_RAWDEV)) {
		p_fsalattr_out->rawdev = posix2fsal_devt(p_buffstat->st_rdev);
		LogFullDebug(COMPONENT_FSAL, "rawdev major = %u, minor = %u",
			     (unsigned int)p_fsalattr_out->rawdev.major,
			     (unsigned int)p_fsalattr_out->rawdev.minor);
	}

	/* everything has been copied ! */

	return fsalstat(ERR_FSAL_NO_ERROR, 0);
}
Ejemplo n.º 7
0
/* Same function as posixstat64_2_fsal_attributes. When NFS4 ACL support
 * is enabled, this will replace posixstat64_2_fsal_attributes. */
fsal_status_t
ptfsal_xstat_2_fsal_attributes(ptfsal_xstat_t     * p_buffxstat,
				 fsal_attrib_list_t * p_fsalattr_out)
{

    fsal_attrib_mask_t supp_attr, unsupp_attr;
    struct stat64 *p_buffstat;

    /* sanity checks */
    if(!p_buffxstat || !p_fsalattr_out)
        ReturnCode(ERR_FSAL_FAULT, 0);

    /* check that asked attributes are supported */
    supp_attr = global_fs_info.supported_attrs;

    unsupp_attr = (p_fsalattr_out->asked_attributes) & (~supp_attr);
    if(unsupp_attr)
        {
            LogFullDebug(COMPONENT_FSAL, "Unsupported attributes: %#llX",
                         unsupp_attr);
            ReturnCode(ERR_FSAL_ATTRNOTSUPP, 0);
        }

    p_buffstat = &p_buffxstat->buffstat;

    /* Initialize ACL regardless of whether ACL was asked or not.
     * This is needed to make sure ACL attribute is initialized. */
    p_fsalattr_out->acl = NULL;

    /* Fills the output struct */
    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_SUPPATTR))
        {
            p_fsalattr_out->supported_attributes = supp_attr;
            LogFullDebug(COMPONENT_FSAL, "supported_attributes = %llu", 
                         p_fsalattr_out->supported_attributes);
        }
    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_TYPE))
        {
            p_fsalattr_out->type = posix2fsal_type(p_buffstat->st_mode);
            LogFullDebug(COMPONENT_FSAL, "type = 0x%x", p_fsalattr_out->type);
        }
    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_SIZE))
        {
            p_fsalattr_out->filesize = p_buffstat->st_size;
            LogFullDebug(COMPONENT_FSAL, "filesize = %lu", 
                         p_fsalattr_out->filesize);
        }
    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_FSID))
        {
            p_fsalattr_out->fsid = posix2fsal_fsid(p_buffstat->st_dev);
            LogFullDebug(COMPONENT_FSAL, "fsid major = %llu, minor = %llu", 
                         p_fsalattr_out->fsid.major, 
                         p_fsalattr_out->fsid.minor);
        }
    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_ACL))
        {
#ifndef _USE_NFS4_ACL
            p_fsalattr_out->acl = NULL;
#else
            if((p_buffxstat->attr_valid & XATTR_ACL) == 0)
              {
                /* ACL is invalid. */
                p_fsalattr_out->acl = NULL;
              }
            else
              {
                /* ACL is valid, so try to convert fsal acl. */
                if(ptfs_acl_2_fsal_acl(p_fsalattr_out,
                   (gpfs_acl_t *)p_buffxstat->buffacl) != ERR_FSAL_NO_ERROR)
                  p_fsalattr_out->acl = NULL;
              }
#endif                          /* _USE_NFS4_ACL */
            LogFullDebug(COMPONENT_FSAL, "acl = %p", p_fsalattr_out->acl);
        }
    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_FILEID))
        {
            p_fsalattr_out->fileid = (fsal_u64_t) (p_buffstat->st_ino);
            LogFullDebug(COMPONENT_FSAL, "fileid = %llu", 
                         p_fsalattr_out->fileid);
        }

    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_MODE))
        {
            p_fsalattr_out->mode = unix2fsal_mode(p_buffstat->st_mode);
            LogFullDebug(COMPONENT_FSAL, "mode = %llu", 
                         (long long unsigned int) p_fsalattr_out->mode);
        }
    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_NUMLINKS))
        {
            p_fsalattr_out->numlinks = p_buffstat->st_nlink;
            LogFullDebug(COMPONENT_FSAL, "numlinks = %lu", 
                         p_fsalattr_out->numlinks);
        }
    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_OWNER))
        {
            p_fsalattr_out->owner = p_buffstat->st_uid;
            LogFullDebug(COMPONENT_FSAL, "owner = %u", p_fsalattr_out->owner);
        }
    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_GROUP))
        {
            p_fsalattr_out->group = p_buffstat->st_gid;
            LogFullDebug(COMPONENT_FSAL, "group = %u", p_fsalattr_out->group);
        }
    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_ATIME))
        {
          p_fsalattr_out->atime = posix2fsal_time(p_buffstat->st_atime, 
                                                  p_buffstat->st_atim.tv_nsec);
            LogFullDebug(COMPONENT_FSAL, "atime = %u", 
                         p_fsalattr_out->atime.seconds);
        }

    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_CTIME))
        {
          p_fsalattr_out->ctime = posix2fsal_time(p_buffstat->st_ctime, 
                                                  p_buffstat->st_ctim.tv_nsec);
            LogFullDebug(COMPONENT_FSAL, "ctime = %u", 
                         p_fsalattr_out->ctime.seconds);
        }
    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_MTIME))
        {
          p_fsalattr_out->mtime = posix2fsal_time(p_buffstat->st_mtime, 
                                                  p_buffstat->st_mtim.tv_nsec);
            LogFullDebug(COMPONENT_FSAL, "mtime = %u", 
                         p_fsalattr_out->mtime.seconds);
        }

    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_CHGTIME))
        {
            p_fsalattr_out->chgtime
              = posix2fsal_time(MAX_2(p_buffstat->st_mtime, 
                                      p_buffstat->st_ctime), 0);
            p_fsalattr_out->change = 
              (uint64_t) p_fsalattr_out->chgtime.seconds ;
            LogFullDebug(COMPONENT_FSAL, "chgtime = %u", 
                         p_fsalattr_out->chgtime.seconds);
        }

    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_SPACEUSED))
        {
            p_fsalattr_out->spaceused = p_buffstat->st_blocks * S_BLKSIZE;
            LogFullDebug(COMPONENT_FSAL, "spaceused = %lu", 
                         p_fsalattr_out->spaceused);
        }

    if(FSAL_TEST_MASK(p_fsalattr_out->asked_attributes, FSAL_ATTR_RAWDEV))
        {
            p_fsalattr_out->rawdev = posix2fsal_devt(p_buffstat->st_rdev);   
            LogFullDebug(COMPONENT_FSAL,
                         "rawdev major = %u, minor = %u",
                         (unsigned int) p_fsalattr_out->rawdev.major,
                         (unsigned int) p_fsalattr_out->rawdev.minor);
        }

    /* everything has been copied ! */

    ReturnCode(ERR_FSAL_NO_ERROR, 0);
}
Ejemplo n.º 8
0
fsal_status_t posixstat64_2_fsal_attributes(struct stat *p_buffstat,
					    struct attrlist *p_fsalattr_out)
{

	/* sanity checks */
	if (!p_buffstat || !p_fsalattr_out)
		return fsalstat(ERR_FSAL_FAULT, 0);

	/* Initialize ACL regardless of whether ACL was asked or not.
	 * This is needed to make sure ACL attribute is initialized. */
	p_fsalattr_out->acl = NULL;

	/* Fills the output struct */
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_TYPE))
		p_fsalattr_out->type = posix2fsal_type(p_buffstat->st_mode);
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_SIZE))
		p_fsalattr_out->filesize = p_buffstat->st_size;
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_FSID))
		p_fsalattr_out->fsid = posix2fsal_fsid(p_buffstat->st_dev);
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_ACL))
		p_fsalattr_out->acl = NULL;
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_FILEID))
		p_fsalattr_out->fileid = (uint64_t) (p_buffstat->st_ino);

	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_MODE))
		p_fsalattr_out->mode = unix2fsal_mode(p_buffstat->st_mode);
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_NUMLINKS))
		p_fsalattr_out->numlinks = p_buffstat->st_nlink;
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_OWNER))
		p_fsalattr_out->owner = p_buffstat->st_uid;
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_GROUP))
		p_fsalattr_out->group = p_buffstat->st_gid;
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_ATIME)) {
		p_fsalattr_out->atime =
		    posix2fsal_time(p_buffstat->st_atime,
				    p_buffstat->st_atim.tv_nsec);

	}

	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_CTIME)) {
		p_fsalattr_out->ctime =
		    posix2fsal_time(p_buffstat->st_ctime,
				    p_buffstat->st_ctim.tv_nsec);
	}
	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_MTIME)) {
		p_fsalattr_out->mtime =
		    posix2fsal_time(p_buffstat->st_mtime,
				    p_buffstat->st_mtim.tv_nsec);
	}

	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_CHGTIME)) {
		p_fsalattr_out->chgtime =
		    posix2fsal_time(MAX
				    (p_buffstat->st_mtime,
				     p_buffstat->st_ctime), 0);
		p_fsalattr_out->change =
		    (uint64_t) p_fsalattr_out->chgtime.tv_sec;
	}

	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_SPACEUSED))
		p_fsalattr_out->spaceused = p_buffstat->st_blocks * S_BLKSIZE;

	if (FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_RAWDEV))
		p_fsalattr_out->rawdev = posix2fsal_devt(p_buffstat->st_rdev);

	/* everything has been copied ! */

	return fsalstat(ERR_FSAL_NO_ERROR, 0);
}
Ejemplo n.º 9
0
/* alloc_handle
 * allocate and fill in a handle
 * this uses malloc/free for the time being.
 */
static struct lustre_fsal_obj_handle *alloc_handle(
				   struct lustre_file_handle *fh,
				   struct fsal_filesystem *fs,
				   struct stat *stat,
				   const char *link_content,
				   struct lustre_file_handle *dir_fh,
				   const char *sock_name,
				   struct fsal_export *exp_hdl)
{
	struct lustre_fsal_obj_handle *hdl;
	fsal_status_t st;

	hdl =
	    gsh_malloc(sizeof(struct lustre_fsal_obj_handle) +
		       sizeof(struct lustre_file_handle));
	if (hdl == NULL)
		return NULL;
	memset(hdl, 0,
	       (sizeof(struct lustre_fsal_obj_handle) +
		sizeof(struct lustre_file_handle)));
	hdl->handle = (struct lustre_file_handle *)&hdl[1];
	memcpy(hdl->handle, fh, sizeof(struct lustre_file_handle));
	hdl->obj_handle.type = posix2fsal_type(stat->st_mode);
	hdl->dev = posix2fsal_devt(stat->st_dev);
	hdl->obj_handle.fs = fs;

	if (hdl->obj_handle.type == REGULAR_FILE) {
		hdl->u.file.fd = -1;	/* no open on this yet */
		hdl->u.file.openflags = FSAL_O_CLOSED;
	} else if (hdl->obj_handle.type == SYMBOLIC_LINK
		   && link_content != NULL) {
		size_t len = strlen(link_content) + 1;

		hdl->u.symlink.link_content = gsh_malloc(len);
		if (hdl->u.symlink.link_content == NULL)
			goto spcerr;

		memcpy(hdl->u.symlink.link_content, link_content, len);
		hdl->u.symlink.link_size = len;
	} else if (hdl->obj_handle.type == SOCKET_FILE && dir_fh != NULL
		   && sock_name != NULL) {
		hdl->u.sock.sock_dir =
		    gsh_malloc(sizeof(struct lustre_file_handle));
		if (hdl->u.sock.sock_dir == NULL)
			goto spcerr;
		memcpy(hdl->u.sock.sock_dir, dir_fh,
		       sizeof(struct lustre_file_handle));
		hdl->u.sock.sock_name = gsh_malloc(strlen(sock_name) + 1);
		if (hdl->u.sock.sock_name == NULL)
			goto spcerr;
		strcpy(hdl->u.sock.sock_name, sock_name);
	}

	hdl->obj_handle.attributes.mask =
	    exp_hdl->ops->fs_supported_attrs(exp_hdl);
	st = posix2fsal_attributes(stat, &hdl->obj_handle.attributes);
	if (FSAL_IS_ERROR(st))
		goto spcerr;
	fsal_obj_handle_init(&hdl->obj_handle, exp_hdl,
			     posix2fsal_type(stat->st_mode));
	return hdl;

 spcerr:
	if (hdl->obj_handle.type == SYMBOLIC_LINK) {
		if (hdl->u.symlink.link_content != NULL)
			gsh_free(hdl->u.symlink.link_content);
	} else if (hdl->obj_handle.type == SOCKET_FILE) {
		if (hdl->u.sock.sock_name != NULL)
			gsh_free(hdl->u.sock.sock_name);
		if (hdl->u.sock.sock_dir != NULL)
			gsh_free(hdl->u.sock.sock_dir);
	}
	gsh_free(hdl);		/* elvis has left the building */
	return NULL;
}
Ejemplo n.º 10
0
/**
 *  @brief convert GPFS xstat to FSAl attributes
 *
 *  @param gpfs_buf Reference to GPFS stat buffer
 *  @param fsal_attr Reference to attribute list
 *  @param use_acl Bool whether ACL are used
 *  @return FSAL status
 *
 *  Same function as posixstat64_2_fsal_attributes. When NFS4 ACL support
 *  is enabled, this will replace posixstat64_2_fsal_attributes.
 */
fsal_status_t
gpfsfsal_xstat_2_fsal_attributes(gpfsfsal_xstat_t *gpfs_buf,
				 struct attrlist *fsal_attr, bool use_acl)
{
	struct stat *p_buffstat;

	/* sanity checks */
	if (!gpfs_buf || !fsal_attr)
		return fsalstat(ERR_FSAL_FAULT, 0);

	p_buffstat = &gpfs_buf->buffstat;

	LogDebug(COMPONENT_FSAL, "inode %ld", p_buffstat->st_ino);

	/* Fills the output struct */
	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_TYPE)) {
		fsal_attr->type = posix2fsal_type(p_buffstat->st_mode);
		LogFullDebug(COMPONENT_FSAL, "type = 0x%x",
			     fsal_attr->type);
	}
	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_SIZE)) {
		fsal_attr->filesize = p_buffstat->st_size;
		LogFullDebug(COMPONENT_FSAL, "filesize = %llu",
			     (unsigned long long)fsal_attr->filesize);
	}
	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_FSID)) {
		fsal_attr->fsid = gpfs_buf->fsal_fsid;
		LogFullDebug(COMPONENT_FSAL,
			     "fsid=0x%016"PRIx64".0x%016"PRIx64,
			     fsal_attr->fsid.major,
			     fsal_attr->fsid.minor);
	}
	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_ACL)) {
		if (fsal_attr->acl != NULL) {
			/* We should never be passed attributes that have an
			 * ACL attached, but just in case some future code
			 * path changes that assumption, let's not release the
			 * old ACL properly.
			 */
			int acl_status;

			acl_status = nfs4_acl_release_entry(fsal_attr->acl);

			if (acl_status != NFS_V4_ACL_SUCCESS)
				LogCrit(COMPONENT_FSAL,
					"Failed to release old acl, status=%d",
					acl_status);

			fsal_attr->acl = NULL;
		}

		if (use_acl && gpfs_buf->attr_valid & XATTR_ACL) {
			/* ACL is valid, so try to convert fsal acl. */
			gpfs_acl_2_fsal_acl(fsal_attr,
					    (gpfs_acl_t *) gpfs_buf->buffacl);
		}
		LogFullDebug(COMPONENT_FSAL, "acl = %p", fsal_attr->acl);
	}
	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_FILEID)) {
		fsal_attr->fileid = (uint64_t) (p_buffstat->st_ino);
		LogFullDebug(COMPONENT_FSAL, "fileid = %" PRIu64,
			     fsal_attr->fileid);
	}

	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_MODE)) {
		fsal_attr->mode = unix2fsal_mode(p_buffstat->st_mode);
		LogFullDebug(COMPONENT_FSAL, "mode = %"PRIu32,
			     fsal_attr->mode);
	}
	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_NUMLINKS)) {
		fsal_attr->numlinks = p_buffstat->st_nlink;
		LogFullDebug(COMPONENT_FSAL, "numlinks = %u",
			     fsal_attr->numlinks);
	}
	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_OWNER)) {
		fsal_attr->owner = p_buffstat->st_uid;
		LogFullDebug(COMPONENT_FSAL, "owner = %" PRIu64,
			     fsal_attr->owner);
	}
	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_GROUP)) {
		fsal_attr->group = p_buffstat->st_gid;
		LogFullDebug(COMPONENT_FSAL, "group = %" PRIu64,
			     fsal_attr->group);
	}
	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_ATIME)) {
		fsal_attr->atime =
		    posix2fsal_time(p_buffstat->st_atime,
				    p_buffstat->st_atim.tv_nsec);
		LogFullDebug(COMPONENT_FSAL, "atime = %lu",
			     fsal_attr->atime.tv_sec);
	}

	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_CTIME)) {
		fsal_attr->ctime =
		    posix2fsal_time(p_buffstat->st_ctime,
				    p_buffstat->st_ctim.tv_nsec);
		LogFullDebug(COMPONENT_FSAL, "ctime = %lu",
			     fsal_attr->ctime.tv_sec);
	}
	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_MTIME)) {
		fsal_attr->mtime =
		    posix2fsal_time(p_buffstat->st_mtime,
				    p_buffstat->st_mtim.tv_nsec);
		LogFullDebug(COMPONENT_FSAL, "mtime = %lu",
			     fsal_attr->mtime.tv_sec);
	}

	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_CHGTIME)) {
		if (p_buffstat->st_mtime == p_buffstat->st_ctime) {
			if (p_buffstat->st_mtim.tv_nsec >
			    p_buffstat->st_ctim.tv_nsec)
				fsal_attr->chgtime =
				    posix2fsal_time(p_buffstat->st_mtime,
						    p_buffstat->st_mtim.
						    tv_nsec);
			else
				fsal_attr->chgtime =
				    posix2fsal_time(p_buffstat->st_ctime,
						    p_buffstat->st_ctim.
						    tv_nsec);
		} else if (p_buffstat->st_mtime > p_buffstat->st_ctime) {
			fsal_attr->chgtime =
			    posix2fsal_time(p_buffstat->st_mtime,
					    p_buffstat->st_mtim.tv_nsec);
		} else {
			fsal_attr->chgtime =
			    posix2fsal_time(p_buffstat->st_ctime,
					    p_buffstat->st_ctim.tv_nsec);
		}
		fsal_attr->change =
		    (uint64_t) fsal_attr->chgtime.tv_sec +
		    (uint64_t) fsal_attr->chgtime.tv_nsec;
		LogFullDebug(COMPONENT_FSAL, "chgtime = %lu",
			     fsal_attr->chgtime.tv_sec);

	}

	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_SPACEUSED)) {
		fsal_attr->spaceused = p_buffstat->st_blocks * S_BLKSIZE;
		LogFullDebug(COMPONENT_FSAL, "spaceused = %llu",
			     (unsigned long long)fsal_attr->spaceused);
	}

	if (FSAL_TEST_MASK(fsal_attr->mask, ATTR_RAWDEV)) {
		fsal_attr->rawdev = posix2fsal_devt(p_buffstat->st_rdev);
		LogFullDebug(COMPONENT_FSAL, "rawdev major = %u, minor = %u",
			     (unsigned int)fsal_attr->rawdev.major,
			     (unsigned int)fsal_attr->rawdev.minor);
	}

	/* everything has been copied ! */

	return fsalstat(ERR_FSAL_NO_ERROR, 0);
}
Ejemplo n.º 11
0
fsal_status_t posix2fsal_attributes(struct stat * p_buffstat,
                                    struct attrlist * p_fsalattr_out)
{
  /* sanity checks */
  if(!p_buffstat || !p_fsalattr_out)
    return fsalstat(ERR_FSAL_FAULT, 0);

  /* Initialize ACL regardless of whether ACL was asked or not.
   * This is needed to make sure ACL attribute is initialized. */
  p_fsalattr_out->acl = NULL;

  /* Fills the output struct */
  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_TYPE))
    {
      p_fsalattr_out->type = posix2fsal_type(p_buffstat->st_mode);
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_SIZE))
    {
      p_fsalattr_out->filesize = p_buffstat->st_size;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_FSID))
    {
      p_fsalattr_out->fsid = posix2fsal_fsid(p_buffstat->st_dev);
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_ACL))
    {
      p_fsalattr_out->acl = NULL;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_FILEID))
    {
      p_fsalattr_out->fileid = (uint64_t) (p_buffstat->st_ino);
    }

  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_MODE))
    {
      p_fsalattr_out->mode = unix2fsal_mode(p_buffstat->st_mode);
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_NUMLINKS))
    {
      p_fsalattr_out->numlinks = p_buffstat->st_nlink;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_OWNER))
    {
      p_fsalattr_out->owner = p_buffstat->st_uid;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_GROUP))
    {
      p_fsalattr_out->group = p_buffstat->st_gid;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_ATIME))
    {
      p_fsalattr_out->atime = p_buffstat->st_atim;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_CTIME))
    {
      p_fsalattr_out->ctime = p_buffstat->st_ctim;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_MTIME))
    {
      p_fsalattr_out->mtime = p_buffstat->st_mtim;
    }
  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_CHGTIME))
    {
      p_fsalattr_out->chgtime =
          (gsh_time_cmp(&p_buffstat->st_mtim,
                        &p_buffstat->st_ctim) > 0) ?
          p_buffstat->st_mtim :
          p_buffstat->st_ctim;
      /* XXX */
      p_fsalattr_out->change = p_fsalattr_out->chgtime.tv_sec +
          p_fsalattr_out->chgtime.tv_nsec;
    }

  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_SPACEUSED))
    {
      p_fsalattr_out->spaceused = p_buffstat->st_blocks * S_BLKSIZE;
    }

  if(FSAL_TEST_MASK(p_fsalattr_out->mask, ATTR_RAWDEV))
    {
      p_fsalattr_out->rawdev = posix2fsal_devt(p_buffstat->st_rdev);    /* XXX: convert ? */
    }
  /* mounted_on_fileid :
     if ( FSAL_TEST_MASK(p_fsalattr_out->mask,
     ATTR_MOUNTFILEID )){
     p_fsalattr_out->mounted_on_fileid = 
     hpss2fsal_64( p_hpss_attr_in->FilesetRootId );
     }
   */

  /* everything has been copied ! */

  return fsalstat(ERR_FSAL_NO_ERROR, 0);
}
Ejemplo n.º 12
0
static struct vfs_fsal_obj_handle *alloc_handle(int dirfd,
						vfs_file_handle_t *fh,
						struct fsal_filesystem *fs,
						struct stat *stat,
						vfs_file_handle_t *dir_fh,
						const char *path,
						struct fsal_export *exp_hdl)
{
	struct vfs_fsal_export *myself =
	    container_of(exp_hdl, struct vfs_fsal_export, export);
	struct vfs_fsal_obj_handle *hdl;
	fsal_status_t st;

	hdl = gsh_calloc(1,
			 (sizeof(struct vfs_fsal_obj_handle) +
			  sizeof(vfs_file_handle_t)));
	if (hdl == NULL)
		return NULL;
	hdl->handle = (vfs_file_handle_t *) &hdl[1];
	memcpy(hdl->handle, fh, sizeof(vfs_file_handle_t));
	hdl->obj_handle.type = posix2fsal_type(stat->st_mode);
	hdl->dev = posix2fsal_devt(stat->st_dev);
	hdl->up_ops = exp_hdl->up_ops;
	hdl->obj_handle.fs = fs;

	if (hdl->obj_handle.type == REGULAR_FILE) {
		hdl->u.file.fd = -1;	/* no open on this yet */
		hdl->u.file.openflags = FSAL_O_CLOSED;
	} else if (hdl->obj_handle.type == SYMBOLIC_LINK) {
		ssize_t retlink;
		size_t len = stat->st_size + 1;
		char *link_content = gsh_malloc(len);

		if (link_content == NULL)
			goto spcerr;

		retlink =
		    vfs_readlink_by_handle(fh, dirfd, path, link_content, len);
		if (retlink < 0 || retlink == len)
			goto spcerr;
		link_content[retlink] = '\0';
		hdl->u.symlink.link_content = link_content;
		hdl->u.symlink.link_size = len;
	} else if (vfs_unopenable_type(hdl->obj_handle.type)) {
		/* AF_UNIX sockets, character special, and block
		   special files  require craziness */
		if (dir_fh == NULL) {
			int retval;
			vfs_alloc_handle(dir_fh);
			retval =
			    vfs_fd_to_handle(dirfd, hdl->obj_handle.fs, fh);
			if (retval < 0)
				goto spcerr;
		}
		hdl->u.unopenable.dir = gsh_malloc(sizeof(vfs_file_handle_t));
		if (hdl->u.unopenable.dir == NULL)
			goto spcerr;
		memcpy(hdl->u.unopenable.dir, dir_fh,
		       sizeof(vfs_file_handle_t));
		hdl->u.unopenable.name = gsh_strdup(path);
		if (hdl->u.unopenable.name == NULL)
			goto spcerr;
	}
	hdl->obj_handle.attributes.mask =
	    exp_hdl->exp_ops.fs_supported_attrs(exp_hdl);
	st = posix2fsal_attributes(stat, &hdl->obj_handle.attributes);
	if (FSAL_IS_ERROR(st))
		goto spcerr;
	hdl->obj_handle.attributes.fsid = fs->fsid;
	fsal_obj_handle_init(&hdl->obj_handle, exp_hdl,
			     posix2fsal_type(stat->st_mode));
	vfs_handle_ops_init(&hdl->obj_handle.obj_ops);
	vfs_sub_init_handle_ops(myself, &hdl->obj_handle.obj_ops);

	return hdl;

 spcerr:
	if (hdl->obj_handle.type == SYMBOLIC_LINK) {
		if (hdl->u.symlink.link_content != NULL)
			gsh_free(hdl->u.symlink.link_content);
	} else if (vfs_unopenable_type(hdl->obj_handle.type)) {
		if (hdl->u.unopenable.name != NULL)
			gsh_free(hdl->u.unopenable.name);
		if (hdl->u.unopenable.dir != NULL)
			gsh_free(hdl->u.unopenable.dir);
	}
	gsh_free(hdl);		/* elvis has left the building */
	return NULL;
}
Ejemplo n.º 13
0
static fsal_status_t lookup(struct fsal_obj_handle *parent,
			    const char *path, struct fsal_obj_handle **handle)
{
	struct vfs_fsal_obj_handle *parent_hdl, *hdl;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int retval, dirfd;
	struct stat stat;
	vfs_file_handle_t *fh = NULL;
	vfs_alloc_handle(fh);
	fsal_dev_t dev;
	struct fsal_filesystem *fs;
	bool xfsal = false;

	*handle = NULL;		/* poison it first */
	parent_hdl =
	    container_of(parent, struct vfs_fsal_obj_handle, obj_handle);
	if (!parent->obj_ops.handle_is(parent, DIRECTORY)) {
		LogCrit(COMPONENT_FSAL,
			"Parent handle is not a directory. hdl = 0x%p", parent);
		return fsalstat(ERR_FSAL_NOTDIR, 0);
	}

	if (parent->fsal != parent->fs->fsal) {
		LogDebug(COMPONENT_FSAL,
			 "FSAL %s operation for handle belonging to FSAL %s, return EXDEV",
			 parent->fsal->name,
			 parent->fs->fsal != NULL
				? parent->fs->fsal->name
				: "(none)");
		retval = EXDEV;
		goto hdlerr;
	}

	fs = parent->fs;
	dirfd = vfs_fsal_open(parent_hdl, O_PATH | O_NOACCESS, &fsal_error);

	if (dirfd < 0)
		return fsalstat(fsal_error, -dirfd);

	retval = fstatat(dirfd, path, &stat, AT_SYMLINK_NOFOLLOW);

	if (retval < 0) {
		retval = errno;
		goto direrr;
	}

	dev = posix2fsal_devt(stat.st_dev);

	if ((dev.minor != parent_hdl->dev.minor) ||
	    (dev.major != parent_hdl->dev.major)) {
		/* XDEV */
		fs = lookup_dev(&dev);
		if (fs == NULL) {
			LogDebug(COMPONENT_FSAL,
				 "Lookup of %s crosses filesystem boundary to "
				 "unknown file system dev=%"PRIu64".%"PRIu64,
				 path, dev.major, dev.minor);
			retval = EXDEV;
			goto direrr;
		}

		if (fs->fsal != parent->fsal) {
			xfsal = true;
			LogDebug(COMPONENT_FSAL,
				 "Lookup of %s crosses filesystem boundary to file system %s into FSAL %s",
				 path, fs->path,
				 fs->fsal != NULL
					? fs->fsal->name
					: "(none)");
		} else {
			LogDebug(COMPONENT_FSAL,
				 "Lookup of %s crosses filesystem boundary to file system %s",
				 path, fs->path);
		}
	}

	if (xfsal || vfs_name_to_handle(dirfd, fs, path, fh) < 0) {
		retval = errno;
		if (((retval == ENOTTY) ||
		     (retval == EOPNOTSUPP) ||
		     (retval == ENOTSUP) ||
		     xfsal) &&
		    (fs != parent->fs)) {
			/* Crossed device into territory not handled by
			 * this FSAL (XFS or VFS). Need to invent a handle.
			 * The made up handle will be JUST the fsid, we
			 * do not expect to see the handle on the wire, and
			 * this handle will not be valid for any form of this
			 * FSAL.
			 */
			LogDebug(COMPONENT_FSAL,
				 "vfs_name_to_handle %s, inventing FSAL %s handle for FSAL %s filesystem %s",
				 xfsal ? "skipped" : "failed",
				 parent->fsal->name,
				 fs->fsal != NULL
					? fs->fsal->name
					: "(none)",
				 path);

			retval = vfs_encode_dummy_handle(fh, fs);

			if (retval < 0) {
				retval = errno;
				goto direrr;
			}

			retval = 0;
		} else {
			/* Some other error */
			goto direrr;
		}
	}

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(dirfd, fh, fs, &stat, parent_hdl->handle, path,
			   op_ctx->fsal_export);
	close(dirfd);
	if (hdl == NULL) {
		retval = ENOMEM;
		goto hdlerr;
	}
	*handle = &hdl->obj_handle;
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 direrr:
	close(dirfd);
 hdlerr:
	fsal_error = posix2fsal_error(retval);
	return fsalstat(fsal_error, retval);
}
Ejemplo n.º 14
0
static struct closefd vfs_fsal_open_and_stat(struct fsal_export *exp,
					     struct vfs_fsal_obj_handle *myself,
					     struct stat *stat, int open_flags,
					     fsal_errors_t *fsal_error)
{
	struct fsal_obj_handle *obj_hdl = &myself->obj_handle;
	struct closefd cfd = { .fd = -1, .close_fd = false };
	int retval = 0;
	vfs_file_handle_t *fh = NULL;
	vfs_alloc_handle(fh);
	const char *func = "unknown";
	struct vfs_filesystem *vfs_fs = myself->obj_handle.fs->private;

	switch (obj_hdl->type) {
	case SOCKET_FILE:
	case CHARACTER_FILE:
	case BLOCK_FILE:
		cfd.fd = vfs_open_by_handle(vfs_fs,
					    myself->u.unopenable.dir,
					    O_PATH | O_NOACCESS,
					    fsal_error);
		if (cfd.fd < 0) {
			LogDebug(COMPONENT_FSAL,
				 "Failed with %s open_flags 0x%08x",
				 strerror(-cfd.fd), O_PATH | O_NOACCESS);
			return cfd;
		}
		cfd.close_fd = true;
		retval =
		    fstatat(cfd.fd, myself->u.unopenable.name, stat,
			    AT_SYMLINK_NOFOLLOW);

		func = "fstatat";
		break;
	case REGULAR_FILE:
		if (myself->u.file.openflags == FSAL_O_CLOSED) {
			/* no file open at the moment */
			cfd.fd = vfs_fsal_open(myself, open_flags, fsal_error);
			if (cfd.fd < 0) {
				LogDebug(COMPONENT_FSAL,
					 "Failed with %s open_flags 0x%08x",
					 strerror(-cfd.fd), open_flags);
				return cfd;
			}
			cfd.close_fd = true;
		} else {
			cfd.fd = myself->u.file.fd;
		}
		retval = fstat(cfd.fd, stat);
		func = "fstat";
		break;
	case SYMBOLIC_LINK:
		open_flags |= (O_PATH | O_RDWR | O_NOFOLLOW);
		goto vfos_open;
	case FIFO_FILE:
		open_flags |= O_NONBLOCK;
		/* fall through */
	case DIRECTORY:
	default:
 vfos_open:
		cfd.fd = vfs_fsal_open(myself, open_flags, fsal_error);
		if (cfd.fd < 0) {
			LogDebug(COMPONENT_FSAL,
				 "Failed with %s open_flags 0x%08x",
				 strerror(-cfd.fd), open_flags);
			return cfd;
		}
		cfd.close_fd = true;
		retval = vfs_stat_by_handle(cfd.fd, myself->handle,
					    stat, open_flags);
		func = "vfs_stat_by_handle";
		break;
	}

	if (retval < 0) {
		retval = errno;
		if (cfd.close_fd) {
			int rc;
			rc = close(cfd.fd);
			if (rc < 0) {
				rc = errno;
				LogDebug(COMPONENT_FSAL, "close failed with %s",
					 strerror(rc));
			}
		}
		if (retval == ENOENT)
			retval = ESTALE;
		*fsal_error = posix2fsal_error(retval);
		LogDebug(COMPONENT_FSAL, "%s failed with %s", func,
			 strerror(retval));
		cfd.fd = -retval;
		cfd.close_fd = false;
		return cfd;
	}
	return cfd;
}

static fsal_status_t getattrs(struct fsal_obj_handle *obj_hdl)
{
	struct vfs_fsal_obj_handle *myself;
	struct closefd cfd = { .fd = -1, .close_fd = false };
	struct stat stat;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	fsal_status_t st;
	int retval = 0;

	myself = container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle);

	if (obj_hdl->fsal != obj_hdl->fs->fsal) {
		LogDebug(COMPONENT_FSAL,
			 "FSAL %s getattr for handle belonging to FSAL %s, ignoring",
			 obj_hdl->fsal->name,
			 obj_hdl->fs->fsal != NULL
				? obj_hdl->fs->fsal->name
				: "(none)");
		goto out;
	}

	cfd = vfs_fsal_open_and_stat(op_ctx->fsal_export, myself, &stat,
				     O_RDONLY, &fsal_error);
	if (cfd.fd >= 0) {
		st = posix2fsal_attributes(&stat, &obj_hdl->attributes);
		if (cfd.close_fd)
			close(cfd.fd);
		if (FSAL_IS_ERROR(st)) {
			FSAL_CLEAR_MASK(obj_hdl->attributes.mask);
			FSAL_SET_MASK(obj_hdl->attributes.mask,
				      ATTR_RDATTR_ERR);
			fsal_error = st.major;
			retval = st.minor;
		} else {
			obj_hdl->attributes.fsid = obj_hdl->fs->fsid;
		}
	} else {
		LogDebug(COMPONENT_FSAL, "Failed with %s, fsal_error %s",
			 strerror(-cfd.fd),
			 fsal_error ==
			 ERR_FSAL_STALE ? "ERR_FSAL_STALE" : "other");
		if (obj_hdl->type == SYMBOLIC_LINK
		    && cfd.fd == -EPERM) {
			/* You cannot open_by_handle (XFS on linux) a symlink
			 * and it throws an EPERM error for it.
			 * open_by_handle_at does not throw that error for
			 * symlinks so we play a game here.  Since there is
			 * not much we can do with symlinks anyway,
			 * say that we did it but don't actually
			 * do anything.  In this case, return the stat we got
			 * at lookup time.  If you *really* want to tweek things
			 * like owners, get a modern linux kernel...
			 */
			fsal_error = ERR_FSAL_NO_ERROR;
			goto out;
		}
		retval = -cfd.fd;
	}

 out:
	return fsalstat(fsal_error, retval);
}

/*
 * NOTE: this is done under protection of the attributes rwlock
 * in the cache entry.
 */

static fsal_status_t setattrs(struct fsal_obj_handle *obj_hdl,
			      struct attrlist *attrs)
{
	struct vfs_fsal_obj_handle *myself;
	struct closefd cfd = { .fd = -1, .close_fd = false };
	struct stat stat;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int retval = 0;
	int open_flags = O_RDONLY;

	/* apply umask, if mode attribute is to be changed */
	if (FSAL_TEST_MASK(attrs->mask, ATTR_MODE))
		attrs->mode &= ~op_ctx->fsal_export->exp_ops.
			fs_umask(op_ctx->fsal_export);
	myself = container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle);
	if (obj_hdl->fsal != obj_hdl->fs->fsal) {
		LogDebug(COMPONENT_FSAL,
			 "FSAL %s operation for handle belonging to FSAL %s, return EXDEV",
			 obj_hdl->fsal->name,
			 obj_hdl->fs->fsal != NULL
				? obj_hdl->fs->fsal->name
				: "(none)");
		retval = EXDEV;
		fsal_error = posix2fsal_error(retval);
		goto hdlerr;
	}

	/* This is yet another "you can't get there from here".  If this object
	 * is a socket (AF_UNIX), an fd on the socket s useless _period_.
	 * If it is for a symlink, without O_PATH, you will get an ELOOP error
	 * and (f)chmod doesn't work for a symlink anyway - not that it matters
	 * because access checking is not done on the symlink but the final
	 * target.
	 * AF_UNIX sockets are also ozone material.  If the socket is already
	 * active listeners et al, you can manipulate the mode etc.  If it is
	 * just sitting there as in you made it with a mknod.
	 * (one of those leaky abstractions...)
	 * or the listener forgot to unlink it, it is lame duck.
	 */

	if (FSAL_TEST_MASK(attrs->mask, ATTR_SIZE))
		open_flags = O_RDWR;

	cfd = vfs_fsal_open_and_stat(op_ctx->fsal_export, myself, &stat,
				     open_flags, &fsal_error);

	if (cfd.fd < 0) {
		if (obj_hdl->type == SYMBOLIC_LINK &&
		    cfd.fd == -EPERM) {
			/* You cannot open_by_handle (XFS) a symlink and it
			 * throws an EPERM error for it.  open_by_handle_at
			 * does not throw that error for symlinks so we play a
			 * game here.  Since there is not much we can do with
			 * symlinks anyway, say that we did it
			 * but don't actually do anything.
			 * If you *really* want to tweek things
			 * like owners, get a modern linux kernel...
			 */
			fsal_error = ERR_FSAL_NO_ERROR;
			goto out;
		}
		return fsalstat(fsal_error, cfd.fd);
	}
	/** TRUNCATE **/
	if (FSAL_TEST_MASK(attrs->mask, ATTR_SIZE)) {
		if (obj_hdl->type != REGULAR_FILE) {
			fsal_error = ERR_FSAL_INVAL;
			goto fileerr;
		}
		retval = ftruncate(cfd.fd, attrs->filesize);
		if (retval != 0) {
			/* XXX ESXi volume creation pattern reliably
			 * reaches this point and reliably can successfully
			 * ftruncate on reopen.  I don't know yet if fd if
			 * we failed to handle a previous error, or what.
			 * I don't see a prior failed op in wireshark. */
			if (retval == -1 /* bad fd */) {
				vfs_close(obj_hdl);
				if (cfd.close_fd)
					close(cfd.fd);
				cfd = vfs_fsal_open_and_stat(
							op_ctx->fsal_export,
							     myself, &stat,
							     open_flags,
							     &fsal_error);
				retval = ftruncate(cfd.fd, attrs->filesize);
				if (retval != 0)
					goto fileerr;
			} else
				goto fileerr;
		}
	}

	/** CHMOD **/
	if (FSAL_TEST_MASK(attrs->mask, ATTR_MODE)) {
		/* The POSIX chmod call doesn't affect the symlink object, but
		 * the entry it points to. So we must ignore it.
		 */
		if (!S_ISLNK(stat.st_mode)) {
			if (vfs_unopenable_type(obj_hdl->type))
				retval = fchmodat(cfd.fd,
						  myself->u.unopenable.name,
						  fsal2unix_mode(attrs->mode),
						  0);
			else
				retval = fchmod(cfd.fd,
						fsal2unix_mode(attrs->mode));

			if (retval != 0)
				goto fileerr;
		}
	}

	/**  CHOWN  **/
	if (FSAL_TEST_MASK(attrs->mask, ATTR_OWNER | ATTR_GROUP)) {
		uid_t user = FSAL_TEST_MASK(attrs->mask, ATTR_OWNER)
		    ? (int)attrs->owner : -1;
		gid_t group = FSAL_TEST_MASK(attrs->mask, ATTR_GROUP)
		    ? (int)attrs->group : -1;

		if (vfs_unopenable_type(obj_hdl->type))
			retval = fchownat(cfd.fd, myself->u.unopenable.name,
					  user, group, AT_SYMLINK_NOFOLLOW);
		else if (obj_hdl->type == SYMBOLIC_LINK)
			retval = fchownat(cfd.fd, "", user, group,
					  AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH);
		else
			retval = fchown(cfd.fd, user, group);

		if (retval)
			goto fileerr;
	}

	/**  UTIME  **/
	if (FSAL_TEST_MASK
	    (attrs->mask,
	     ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SERVER | ATTR_MTIME_SERVER)) {
		struct timespec timebuf[2];

		if (obj_hdl->type == SYMBOLIC_LINK)
			goto out; /* Setting time on symlinks is illegal */
		/* Atime */
		if (FSAL_TEST_MASK(attrs->mask, ATTR_ATIME_SERVER)) {
			timebuf[0].tv_sec = 0;
			timebuf[0].tv_nsec = UTIME_NOW;
		} else if (FSAL_TEST_MASK(attrs->mask, ATTR_ATIME)) {
			timebuf[0] = attrs->atime;
		} else {
			timebuf[0].tv_sec = 0;
			timebuf[0].tv_nsec = UTIME_OMIT;
		}

		/* Mtime */
		if (FSAL_TEST_MASK(attrs->mask, ATTR_MTIME_SERVER)) {
			timebuf[1].tv_sec = 0;
			timebuf[1].tv_nsec = UTIME_NOW;
		} else if (FSAL_TEST_MASK(attrs->mask, ATTR_MTIME)) {
			timebuf[1] = attrs->mtime;
		} else {
			timebuf[1].tv_sec = 0;
			timebuf[1].tv_nsec = UTIME_OMIT;
		}
		if (vfs_unopenable_type(obj_hdl->type))
			retval = vfs_utimesat(cfd.fd, myself->u.unopenable.name,
					      timebuf, AT_SYMLINK_NOFOLLOW);
		else
			retval = vfs_utimes(cfd.fd, timebuf);
		if (retval != 0)
			goto fileerr;
	}
	goto out;

 fileerr:
	retval = errno;
	fsal_error = posix2fsal_error(retval);
 out:
	if (cfd.close_fd)
		close(cfd.fd);
 hdlerr:
	return fsalstat(fsal_error, retval);
}

/* file_unlink
 * unlink the named file in the directory
 */

static fsal_status_t file_unlink(struct fsal_obj_handle *dir_hdl,
				 const char *name)
{
	struct vfs_fsal_obj_handle *myself;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	struct stat stat;
	int fd;
	int retval = 0;

	myself = container_of(dir_hdl, struct vfs_fsal_obj_handle, obj_handle);
	if (dir_hdl->fsal != dir_hdl->fs->fsal) {
		LogDebug(COMPONENT_FSAL,
			 "FSAL %s operation for handle belonging to FSAL %s, return EXDEV",
			 dir_hdl->fsal->name,
			 dir_hdl->fs->fsal != NULL
				? dir_hdl->fs->fsal->name
				: "(none)");
		retval = EXDEV;
		fsal_error = posix2fsal_error(retval);
		goto out;
	}
	fd = vfs_fsal_open(myself, O_PATH | O_NOACCESS, &fsal_error);
	if (fd < 0) {
		retval = -fd;
		goto out;
	}
	retval = fstatat(fd, name, &stat, AT_SYMLINK_NOFOLLOW);
	if (retval < 0) {
		retval = errno;
		LogDebug(COMPONENT_FSAL, "fstatat %s failed %s", name,
			 strerror(retval));
		if (retval == ENOENT)
			fsal_error = ERR_FSAL_STALE;
		else
			fsal_error = posix2fsal_error(retval);
		goto errout;
	}
	fsal_set_credentials(op_ctx->creds);
	retval = unlinkat(fd, name, (S_ISDIR(stat.st_mode)) ? AT_REMOVEDIR : 0);
	if (retval < 0) {
		retval = errno;
		if (retval == ENOENT)
			fsal_error = ERR_FSAL_STALE;
		else
			fsal_error = posix2fsal_error(retval);
	}
	fsal_restore_ganesha_credentials();

 errout:
	close(fd);
 out:
	return fsalstat(fsal_error, retval);
}

/* handle_digest
 * fill in the opaque f/s file handle part.
 * we zero the buffer to length first.  This MAY already be done above
 * at which point, remove memset here because the caller is zeroing
 * the whole struct.
 */

static fsal_status_t handle_digest(const struct fsal_obj_handle *obj_hdl,
				   fsal_digesttype_t output_type,
				   struct gsh_buffdesc *fh_desc)
{
	const struct vfs_fsal_obj_handle *myself;

	myself = container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle);

	if (obj_hdl->fsal != obj_hdl->fs->fsal) {
		/* Log, but allow digest */
		LogDebug(COMPONENT_FSAL,
			 "FSAL %s operation for handle belonging to FSAL %s",
			 obj_hdl->fsal->name,
			 obj_hdl->fs->fsal != NULL
				? obj_hdl->fs->fsal->name
				: "(none)");
	}

	switch (output_type) {
	case FSAL_DIGEST_NFSV3:
	case FSAL_DIGEST_NFSV4:
		if (fh_desc->len < myself->handle->handle_len) {
			LogMajor(COMPONENT_FSAL,
				 "Space too small for handle.  need %d, have %lu",
				 (int) myself->handle->handle_len,
				 fh_desc->len);
			return fsalstat(ERR_FSAL_TOOSMALL, 0);
		}
		memcpy(fh_desc->addr,
		       myself->handle->handle_data,
		       myself->handle->handle_len);
		break;
	default:
		return fsalstat(ERR_FSAL_SERVERFAULT, 0);
	}

	fh_desc->len = myself->handle->handle_len;
	return fsalstat(ERR_FSAL_NO_ERROR, 0);
}

/**
 * handle_to_key
 * return a handle descriptor into the handle in this object handle
 * @TODO reminder.  make sure things like hash keys don't point here
 * after the handle is released.
 */

static void handle_to_key(struct fsal_obj_handle *obj_hdl,
			  struct gsh_buffdesc *fh_desc)
{
	struct vfs_fsal_obj_handle *myself;

	myself = container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle);

	fh_desc->addr = myself->handle->handle_data;
	fh_desc->len = myself->handle->handle_len;
}

/*
 * release
 * release our export first so they know we are gone
 */

static void release(struct fsal_obj_handle *obj_hdl)
{
	struct vfs_fsal_obj_handle *myself;
	object_file_type_t type = obj_hdl->type;

	myself = container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle);

	if (type == REGULAR_FILE) {
		fsal_status_t st = vfs_close(obj_hdl);
		if (FSAL_IS_ERROR(st)) {
			LogCrit(COMPONENT_FSAL,
				"Could not close hdl 0x%p, error %s(%d)",
				obj_hdl, strerror(st.minor), st.minor);
		}
	}

	fsal_obj_handle_fini(obj_hdl);

	if (type == SYMBOLIC_LINK) {
		if (myself->u.symlink.link_content != NULL)
			gsh_free(myself->u.symlink.link_content);
	} else if (vfs_unopenable_type(type)) {
		if (myself->u.unopenable.name != NULL)
			gsh_free(myself->u.unopenable.name);
		if (myself->u.unopenable.dir != NULL)
			gsh_free(myself->u.unopenable.dir);
	}

	gsh_free(myself);
}

void vfs_handle_ops_init(struct fsal_obj_ops *ops)
{
	ops->release = release;
	ops->lookup = lookup;
	ops->readdir = read_dirents;
	ops->create = create;
	ops->mkdir = makedir;
	ops->mknode = makenode;
	ops->symlink = makesymlink;
	ops->readlink = readsymlink;
	ops->test_access = fsal_test_access;
	ops->getattrs = getattrs;
	ops->setattrs = setattrs;
	ops->link = linkfile;
	ops->rename = renamefile;
	ops->unlink = file_unlink;
	ops->open = vfs_open;
	ops->status = vfs_status;
	ops->read = vfs_read;
	ops->write = vfs_write;
	ops->commit = vfs_commit;
	ops->lock_op = vfs_lock_op;
	ops->close = vfs_close;
	ops->lru_cleanup = vfs_lru_cleanup;
	ops->handle_digest = handle_digest;
	ops->handle_to_key = handle_to_key;

	/* xattr related functions */
	ops->list_ext_attrs = vfs_list_ext_attrs;
	ops->getextattr_id_by_name = vfs_getextattr_id_by_name;
	ops->getextattr_value_by_name = vfs_getextattr_value_by_name;
	ops->getextattr_value_by_id = vfs_getextattr_value_by_id;
	ops->setextattr_value = vfs_setextattr_value;
	ops->setextattr_value_by_id = vfs_setextattr_value_by_id;
	ops->getextattr_attrs = vfs_getextattr_attrs;
	ops->remove_extattr_by_id = vfs_remove_extattr_by_id;
	ops->remove_extattr_by_name = vfs_remove_extattr_by_name;

}

/* export methods that create object handles
 */

/* lookup_path
 * modeled on old api except we don't stuff attributes.
 * KISS
 */

fsal_status_t vfs_lookup_path(struct fsal_export *exp_hdl,
			      const char *path, struct fsal_obj_handle **handle)
{
	int dir_fd = -1;
	struct stat stat;
	struct vfs_fsal_obj_handle *hdl;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int retval = 0;
	struct fsal_filesystem *fs;
	struct fsal_dev__ dev;
	vfs_file_handle_t *fh = NULL;

	vfs_alloc_handle(fh);

	*handle = NULL;	/* poison it */

	dir_fd = open_dir_by_path_walk(-1, path, &stat);

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

	dev = posix2fsal_devt(stat.st_dev);
	fs = lookup_dev(&dev);

	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);

	retval = vfs_fd_to_handle(dir_fd, fs, fh);

	if (retval < 0) {
		retval = errno;
		LogCrit(COMPONENT_FSAL,
			"Could not get handle for path %s, error %s",
			path, strerror(retval));
		goto errout;
	}

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

	if (hdl == NULL) {
		retval = ENOMEM;
		LogCrit(COMPONENT_FSAL,
			"Could not allocate handle for path %s",
			path);
		goto errout;
	}

	close(dir_fd);

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

 errout:
	if (dir_fd >= 0)
		close(dir_fd);
	fsal_error = posix2fsal_error(retval);
	return fsalstat(fsal_error, retval);
}

fsal_status_t vfs_check_handle(struct fsal_export *exp_hdl,
			       struct gsh_buffdesc *hdl_desc,
			       struct fsal_filesystem **fs,
			       vfs_file_handle_t *fh,
			       bool *dummy)
{
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int retval = 0;
	struct fsal_fsid__ fsid;
	enum fsid_type fsid_type;

	*fs = NULL;

	if (!vfs_valid_handle(hdl_desc))
		return fsalstat(ERR_FSAL_BADHANDLE, 0);

	memcpy(fh->handle_data, hdl_desc->addr, hdl_desc->len);
	fh->handle_len = hdl_desc->len;

	*dummy = vfs_is_dummy_handle(fh);

	retval = vfs_extract_fsid(fh, &fsid_type, &fsid);

	if (retval == 0) {
		*fs = lookup_fsid(&fsid, fsid_type);
		if (*fs == NULL) {
			LogInfo(COMPONENT_FSAL,
				"Could not map "
				"fsid=0x%016"PRIx64".0x%016"PRIx64
				" to filesytem",
				fsid.major, fsid.minor);
			retval = ESTALE;
			fsal_error = posix2fsal_error(retval);
			goto errout;
		}
		if (((*fs)->fsal != exp_hdl->fsal) && !(*dummy)) {
			LogInfo(COMPONENT_FSAL,
				"fsid=0x%016"PRIx64".0x%016"PRIx64
				" in handle not a %s filesystem",
				fsid.major, fsid.minor,
				exp_hdl->fsal->name);
			retval = ESTALE;
			fsal_error = posix2fsal_error(retval);
			goto errout;
		}

		LogDebug(COMPONENT_FSAL,
			 "Found filesystem %s for handle for FSAL %s",
			 (*fs)->path,
			 (*fs)->fsal != NULL ? (*fs)->fsal->name : "(none)");
	} else {
		LogDebug(COMPONENT_FSAL,
			 "Could not map handle to fsid");
		fsal_error = ERR_FSAL_BADHANDLE;
		goto errout;
	}

 errout:
	return fsalstat(fsal_error, retval);
}