- sbp->f_blocks = fs->fs_dsize;
- sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag +
- fs->fs_cstotal.cs_nffree;
- sbp->f_bavail = freespace(fs, fs->fs_minfree);
- sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO;
- sbp->f_ffree = fs->fs_cstotal.cs_nifree;
- if (sbp != &mp->mnt_stat) {
- sbp->f_type = mp->mnt_vfc->vfc_typenum;
- bcopy((caddr_t)mp->mnt_stat.f_mntonname,
- (caddr_t)&sbp->f_mntonname[0], MNAMELEN);
- bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
- (caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
+ sbp->f_blocks = (uint64_t)((unsigned long)fs->fs_dsize);
+ sbp->f_bfree = (uint64_t) ((unsigned long)(fs->fs_cstotal.cs_nbfree * fs->fs_frag +
+ fs->fs_cstotal.cs_nffree));
+ sbp->f_bavail = (uint64_t) ((unsigned long)freespace(fs, fs->fs_minfree));
+ sbp->f_files = (uint64_t) ((unsigned long)(fs->fs_ncg * fs->fs_ipg - ROOTINO));
+ sbp->f_ffree = (uint64_t) ((unsigned long)fs->fs_cstotal.cs_nifree);
+ return (0);
+}
+
+int
+ffs_vfs_getattr(mp, fsap, context)
+ struct mount *mp;
+ struct vfs_attr *fsap;
+ vfs_context_t context;
+{
+ struct ufsmount *ump;
+ struct fs *fs;
+ kauth_cred_t cred;
+ struct vnode *devvp;
+ struct buf *bp;
+ struct ufslabel *ulp;
+ char *offset;
+ int bs, error, length;
+
+ ump = VFSTOUFS(mp);
+ fs = ump->um_fs;
+ cred = vfs_context_ucred(context);
+
+ VFSATTR_RETURN(fsap, f_bsize, fs->fs_fsize);
+ VFSATTR_RETURN(fsap, f_iosize, fs->fs_bsize);
+ VFSATTR_RETURN(fsap, f_blocks, (uint64_t)((unsigned long)fs->fs_dsize));
+ VFSATTR_RETURN(fsap, f_bfree, (uint64_t)((unsigned long)
+ (fs->fs_cstotal.cs_nbfree * fs->fs_frag +
+ fs->fs_cstotal.cs_nffree)));
+ VFSATTR_RETURN(fsap, f_bavail, (uint64_t)((unsigned long)freespace(fs,
+ fs->fs_minfree)));
+ VFSATTR_RETURN(fsap, f_files, (uint64_t)((unsigned long)
+ (fs->fs_ncg * fs->fs_ipg - ROOTINO)));
+ VFSATTR_RETURN(fsap, f_ffree, (uint64_t)((unsigned long)
+ fs->fs_cstotal.cs_nifree));
+
+ if (VFSATTR_IS_ACTIVE(fsap, f_fsid)) {
+ fsap->f_fsid.val[0] = mp->mnt_vfsstat.f_fsid.val[0];
+ fsap->f_fsid.val[1] = mp->mnt_vfsstat.f_fsid.val[1];
+ VFSATTR_SET_SUPPORTED(fsap, f_fsid);
+ }
+
+ if (VFSATTR_IS_ACTIVE(fsap, f_vol_name)) {
+ devvp = ump->um_devvp;
+ bs = vfs_devblocksize(mp);
+
+ if (error = (int)buf_meta_bread(devvp,
+ (daddr64_t)(UFS_LABEL_OFFSET / bs),
+ MAX(bs, UFS_LABEL_SIZE), cred, &bp)) {
+ if (bp)
+ buf_brelse(bp);
+ return (error);
+ }
+
+ /*
+ * Since the disklabel is read directly by older user space
+ * code, make sure this buffer won't remain in the cache when
+ * we release it.
+ */
+ buf_setflags(bp, B_NOCACHE);
+
+ offset = buf_dataptr(bp) + (UFS_LABEL_OFFSET % bs);
+ ulp = (struct ufslabel *)offset;
+
+ if (ufs_label_check(ulp)) {
+ length = ulp->ul_namelen;
+#if REV_ENDIAN_FS
+ if (mp->mnt_flag & MNT_REVEND)
+ length = OSSwapInt16(length);
+#endif
+ if (length > 0 && length <= UFS_MAX_LABEL_NAME) {
+ bcopy(ulp->ul_name, fsap->f_vol_name, length);
+ fsap->f_vol_name[UFS_MAX_LABEL_NAME - 1] = '\0';
+ fsap->f_vol_name[length] = '\0';
+ }
+ }
+
+ buf_brelse(bp);
+ VFSATTR_SET_SUPPORTED(fsap, f_vol_name);