Example #1
0
/*
 * No locking required because I held the root vnode before calling this
 * function so the vfs won't disappear on me.  To be more explicit:
 * fdvrootp->v_count will be greater than 1 so fdunmount will just return.
 */
static int
fdstatvfs(struct vfs *vfsp, struct statvfs64 *sp)
{
	dev32_t d32;
	rctl_qty_t fdno_ctl;

	mutex_enter(&curproc->p_lock);
	fdno_ctl = rctl_enforced_value(rctlproc_legacy[RLIMIT_NOFILE],
	    curproc->p_rctls, curproc);
	mutex_exit(&curproc->p_lock);

	bzero(sp, sizeof (*sp));
	sp->f_bsize = 1024;
	sp->f_frsize = 1024;
	sp->f_blocks = (fsblkcnt64_t)0;
	sp->f_bfree = (fsblkcnt64_t)0;
	sp->f_bavail = (fsblkcnt64_t)0;
	sp->f_files = (fsfilcnt64_t)
	    (MIN(P_FINFO(curproc)->fi_nfiles, fdno_ctl + 2));
	sp->f_ffree = (fsfilcnt64_t)0;
	sp->f_favail = (fsfilcnt64_t)0;
	(void) cmpldev(&d32, vfsp->vfs_dev);
	sp->f_fsid = d32;
	(void) strcpy(sp->f_basetype, vfssw[fdfstype].vsw_name);
	sp->f_flag = vf_to_stf(vfsp->vfs_flag);
	sp->f_namemax = FDNSIZE;
	(void) strcpy(sp->f_fstr, "/dev/fd");
	(void) strcpy(&sp->f_fstr[8], "/dev/fd");
	return (0);
}
Example #2
0
/*
 * Return in sp the status of this file system.
 */
static int
nm_statvfs(vfs_t *vfsp, struct statvfs64 *sp)
{
	dev32_t d32;

	bzero(sp, sizeof (*sp));
	sp->f_bsize	= 1024;
	sp->f_frsize	= 1024;
	(void) cmpldev(&d32, vfsp->vfs_dev);
	sp->f_fsid = d32;
	(void) strcpy(sp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name);
	sp->f_flag	= vf_to_stf(vfsp->vfs_flag);
	return (0);
}
static int
objfs_statvfs(vfs_t *vfsp, statvfs64_t *sp)
{
	dev32_t d32;
	int total = objfs_nobjs();

	bzero(sp, sizeof (*sp));
	sp->f_bsize = DEV_BSIZE;
	sp->f_frsize = DEV_BSIZE;
	sp->f_files = total;
	sp->f_ffree = sp->f_favail = INT_MAX - total;
	(void) cmpldev(&d32, vfsp->vfs_dev);
	sp->f_fsid = d32;
	(void) strlcpy(sp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name,
	    sizeof (sp->f_basetype));
	sp->f_flag = vf_to_stf(vfsp->vfs_flag);
	sp->f_namemax = OBJFS_NAME_MAX;
	(void) strlcpy(sp->f_fstr, "object", sizeof (sp->f_fstr));

	return (0);
}
Example #4
0
/*
 * ctfs_statvfs - the VFS_STATVFS entry point
 */
static int
ctfs_statvfs(vfs_t *vfsp, statvfs64_t *sp)
{
	dev32_t	d32;
	int	total, i;

	bzero(sp, sizeof (*sp));
	sp->f_bsize = DEV_BSIZE;
	sp->f_frsize = DEV_BSIZE;
	for (i = 0, total = 0; i < ct_ntypes; i++)
		total += contract_type_count(ct_types[i]);
	sp->f_files = total;
	sp->f_favail = sp->f_ffree = INT_MAX - total;
	(void) cmpldev(&d32, vfsp->vfs_dev);
	sp->f_fsid = d32;
	(void) strlcpy(sp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name,
	    sizeof (sp->f_basetype));
	sp->f_flag = vf_to_stf(vfsp->vfs_flag);
	sp->f_namemax = CTFS_NAME_MAX;
	(void) strlcpy(sp->f_fstr, "contract", sizeof (sp->f_fstr));

	return (0);
}
Example #5
0
static int
zfs_vfs_getattr(struct mount *mp, struct vfs_attr *fsap, __unused vfs_context_t context)
{
	zfsvfs_t *zfsvfs = vfs_fsprivate(mp);
	uint64_t refdbytes, availbytes, usedobjs, availobjs;

	ZFS_ENTER(zfsvfs);

	dmu_objset_space(zfsvfs->z_os,
	    &refdbytes, &availbytes, &usedobjs, &availobjs);

	VFSATTR_RETURN(fsap, f_objcount, usedobjs);
	VFSATTR_RETURN(fsap, f_maxobjcount, 0x7fffffffffffffff);
	/*
	 * Carbon depends on f_filecount and f_dircount so
	 * make up some values based on total objects.
	 */
	VFSATTR_RETURN(fsap, f_filecount, usedobjs - (usedobjs / 4));
	VFSATTR_RETURN(fsap, f_dircount, usedobjs / 4);

	/*
	 * The underlying storage pool actually uses multiple block sizes.
	 * We report the fragsize as the smallest block size we support,
	 * and we report our blocksize as the filesystem's maximum blocksize.
	 */
	VFSATTR_RETURN(fsap, f_bsize, 1UL << SPA_MINBLOCKSHIFT);
	VFSATTR_RETURN(fsap, f_iosize, zfsvfs->z_max_blksz);

	/*
	 * The following report "total" blocks of various kinds in the
	 * file system, but reported in terms of f_frsize - the
	 * "fragment" size.
	 */
	VFSATTR_RETURN(fsap, f_blocks,
	               (u_int64_t)((refdbytes + availbytes) >> SPA_MINBLOCKSHIFT));
	VFSATTR_RETURN(fsap, f_bfree, (u_int64_t)(availbytes >> SPA_MINBLOCKSHIFT));
	VFSATTR_RETURN(fsap, f_bavail, fsap->f_bfree);  /* no root reservation */
	VFSATTR_RETURN(fsap, f_bused, fsap->f_blocks - fsap->f_bfree);

	/*
	 * statvfs() should really be called statufs(), because it assumes
	 * static metadata.  ZFS doesn't preallocate files, so the best
	 * we can do is report the max that could possibly fit in f_files,
	 * and that minus the number actually used in f_ffree.
	 * For f_ffree, report the smaller of the number of object available
	 * and the number of blocks (each object will take at least a block).
	 */
	VFSATTR_RETURN(fsap, f_ffree, (u_int64_t)MIN(availobjs, fsap->f_bfree));
	VFSATTR_RETURN(fsap, f_files,  fsap->f_ffree + usedobjs);

#if 0
	statp->f_flag = vf_to_stf(vfsp->vfs_flag);
#endif

	if (VFSATTR_IS_ACTIVE(fsap, f_fsid)) {
		VFSATTR_RETURN(fsap, f_fsid, vfs_statfs(mp)->f_fsid);
	}
	if (VFSATTR_IS_ACTIVE(fsap, f_capabilities)) {
		bcopy(&zfs_capabilities, &fsap->f_capabilities, sizeof (zfs_capabilities));
		VFSATTR_SET_SUPPORTED(fsap, f_capabilities);
	}
	if (VFSATTR_IS_ACTIVE(fsap, f_attributes)) {
		bcopy(&zfs_attributes, &fsap->f_attributes.validattr, sizeof (zfs_attributes));
		bcopy(&zfs_attributes, &fsap->f_attributes.nativeattr, sizeof (zfs_attributes));
		VFSATTR_SET_SUPPORTED(fsap, f_attributes);
	}
	if (VFSATTR_IS_ACTIVE(fsap, f_create_time)) {
		dmu_objset_stats_t dmu_stat;

		dmu_objset_fast_stat(zfsvfs->z_os, &dmu_stat);
		fsap->f_create_time.tv_sec = dmu_stat.dds_creation_time;
		fsap->f_create_time.tv_nsec = 0;
		VFSATTR_SET_SUPPORTED(fsap, f_create_time);
	}
	if (VFSATTR_IS_ACTIVE(fsap, f_modify_time)) {
		if (zfsvfs->z_mtime_vp != NULL) {
			znode_t *mzp;

			mzp = VTOZ(zfsvfs->z_mtime_vp);
			ZFS_TIME_DECODE(&fsap->f_modify_time, mzp->z_phys->zp_mtime);
		} else {
			fsap->f_modify_time.tv_sec = 0;
			fsap->f_modify_time.tv_nsec = 0;
		}
		VFSATTR_SET_SUPPORTED(fsap, f_modify_time);
	}
	/*
	 * For Carbon compatibility, pretend to support this legacy/unused 
	 * attribute
	 */
	if (VFSATTR_IS_ACTIVE(fsap, f_backup_time)) {
		fsap->f_backup_time.tv_sec = 0;
		fsap->f_backup_time.tv_nsec = 0;
		VFSATTR_SET_SUPPORTED(fsap, f_backup_time);
	}
	if (VFSATTR_IS_ACTIVE(fsap, f_vol_name)) {
		spa_t *spa = dmu_objset_spa(zfsvfs->z_os);
		spa_config_enter(spa, RW_READER, FTAG);
		strlcpy(fsap->f_vol_name, spa_name(spa), MAXPATHLEN);
		spa_config_exit(spa, FTAG);
		VFSATTR_SET_SUPPORTED(fsap, f_vol_name);
	}
	VFSATTR_RETURN(fsap, f_fssubtype, 0);
	VFSATTR_RETURN(fsap, f_signature, 0x5a21);  /* 'Z!' */
	VFSATTR_RETURN(fsap, f_carbon_fsid, 0);

	ZFS_EXIT(zfsvfs);
	return (0);
}
Example #6
0
static int
zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp)
{
	zfsvfs_t *zfsvfs = vfsp->vfs_data;
	dmu_objset_stats_t dstats;
	dev32_t d32;

	ZFS_ENTER(zfsvfs);

	dmu_objset_stats(zfsvfs->z_os, &dstats);

	/*
	 * The underlying storage pool actually uses multiple block sizes.
	 * We report the fragsize as the smallest block size we support,
	 * and we report our blocksize as the filesystem's maximum blocksize.
	 */
	statp->f_frsize = 1UL << SPA_MINBLOCKSHIFT;
	statp->f_bsize = zfsvfs->z_max_blksz;

	/*
	 * The following report "total" blocks of various kinds in the
	 * file system, but reported in terms of f_frsize - the
	 * "fragment" size.
	 */

	statp->f_blocks =
	    (dstats.dds_space_refd + dstats.dds_available) >> SPA_MINBLOCKSHIFT;
	statp->f_bfree = dstats.dds_available >> SPA_MINBLOCKSHIFT;
	statp->f_bavail = statp->f_bfree; /* no root reservation */

	/*
	 * statvfs() should really be called statufs(), because it assumes
	 * static metadata.  ZFS doesn't preallocate files, so the best
	 * we can do is report the max that could possibly fit in f_files,
	 * and that minus the number actually used in f_ffree.
	 * For f_ffree, report the smaller of the number of object available
	 * and the number of blocks (each object will take at least a block).
	 */
	statp->f_ffree = MIN(dstats.dds_objects_avail, statp->f_bfree);
	statp->f_favail = statp->f_ffree;	/* no "root reservation" */
	statp->f_files = statp->f_ffree + dstats.dds_objects_used;

	(void) cmpldev(&d32, vfsp->vfs_dev);
	statp->f_fsid = d32;

	/*
	 * We're a zfs filesystem.
	 */
	(void) strcpy(statp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name);

	statp->f_flag = vf_to_stf(vfsp->vfs_flag);

	statp->f_namemax = ZFS_MAXNAMELEN;

	/*
	 * We have all of 32 characters to stuff a string here.
	 * Is there anything useful we could/should provide?
	 */
	bzero(statp->f_fstr, sizeof (statp->f_fstr));

	ZFS_EXIT(zfsvfs);
	return (0);
}
Example #7
0
/*
 * Get file system statistics.
 */
static int
smbfs_statvfs(vfs_t *vfsp, statvfs64_t *sbp)
{
	int		error;
	smbmntinfo_t	*smi = VFTOSMI(vfsp);
	smb_share_t	*ssp = smi->smi_share;
	statvfs64_t	stvfs;
	hrtime_t now;
	smb_cred_t	scred;

	if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
		return (EPERM);

	if (smi->smi_flags & SMI_DEAD || vfsp->vfs_flag & VFS_UNMOUNTED)
		return (EIO);

	mutex_enter(&smi->smi_lock);

	/*
	 * Use cached result if still valid.
	 */
recheck:
	now = gethrtime();
	if (now < smi->smi_statfstime) {
		error = 0;
		goto cache_hit;
	}

	/*
	 * FS attributes are stale, so someone
	 * needs to do an OTW call to get them.
	 * Serialize here so only one thread
	 * does the OTW call.
	 */
	if (smi->smi_status & SM_STATUS_STATFS_BUSY) {
		smi->smi_status |= SM_STATUS_STATFS_WANT;
		if (!cv_wait_sig(&smi->smi_statvfs_cv, &smi->smi_lock)) {
			mutex_exit(&smi->smi_lock);
			return (EINTR);
		}
		/* Hope status is valid now. */
		goto recheck;
	}
	smi->smi_status |= SM_STATUS_STATFS_BUSY;
	mutex_exit(&smi->smi_lock);

	/*
	 * Do the OTW call.  Note: lock NOT held.
	 */
	smb_credinit(&scred, NULL);
	bzero(&stvfs, sizeof (stvfs));
	error = smbfs_smb_statfs(ssp, &stvfs, &scred);
	smb_credrele(&scred);
	if (error) {
		SMBVDEBUG("statfs error=%d\n", error);
	} else {

		/*
		 * Set a few things the OTW call didn't get.
		 */
		stvfs.f_frsize = stvfs.f_bsize;
		stvfs.f_favail = stvfs.f_ffree;
		stvfs.f_fsid = (unsigned long)vfsp->vfs_fsid.val[0];
		bcopy(fs_type_name, stvfs.f_basetype, FSTYPSZ);
		stvfs.f_flag	= vf_to_stf(vfsp->vfs_flag);
		stvfs.f_namemax	= smi->smi_fsa.fsa_maxname;

		/*
		 * Save the result, update lifetime
		 */
		now = gethrtime();
		smi->smi_statfstime = now +
		    (SM_MAX_STATFSTIME * (hrtime_t)NANOSEC);
		smi->smi_statvfsbuf = stvfs; /* struct assign! */
	}

	mutex_enter(&smi->smi_lock);
	if (smi->smi_status & SM_STATUS_STATFS_WANT)
		cv_broadcast(&smi->smi_statvfs_cv);
	smi->smi_status &= ~(SM_STATUS_STATFS_BUSY | SM_STATUS_STATFS_WANT);

	/*
	 * Copy the statvfs data to caller's buf.
	 * Note: struct assignment
	 */
cache_hit:
	if (error == 0)
		*sbp = smi->smi_statvfsbuf;
	mutex_exit(&smi->smi_lock);
	return (error);
}