Exemple #1
0
/*
 * smbfs_statfs call
 */
int
smbfs_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred)
{
	struct smbmount *smp = VFSTOSMBFS(mp);
	struct smbnode *np = smp->sm_root;
	struct smb_share *ssp = smp->sm_share;
	struct smb_cred scred;
	int error = 0;

	if (np == NULL)
		return EINVAL;
	
	sbp->f_iosize = SSTOVC(ssp)->vc_txmax;		/* optimal transfer block size */
	sbp->f_spare2 = 0;			/* placeholder */
	smb_makescred(&scred, curthread, cred);

	if (SMB_DIALECT(SSTOVC(ssp)) >= SMB_DIALECT_LANMAN2_0)
		error = smbfs_smb_statfs2(ssp, sbp, &scred);
	else
		error = smbfs_smb_statfs(ssp, sbp, &scred);
	if (error)
		return error;
	sbp->f_flags = 0;		/* copy of mount exported flags */
	if (sbp != &mp->mnt_stat) {
		sbp->f_fsid = mp->mnt_stat.f_fsid;	/* file system id */
		sbp->f_owner = mp->mnt_stat.f_owner;	/* user that mounted the filesystem */
		sbp->f_type = mp->mnt_vfc->vfc_typenum;	/* type of filesystem */
		bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
	}
	strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN);
	return 0;
}
Exemple #2
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);
}