@@ -819,81 +819,105 @@ xfs_fs_sync_fs(
819819 return 0 ;
820820}
821821
822- STATIC int
823- xfs_fs_statfs (
824- struct dentry * dentry ,
825- struct kstatfs * statp )
822+ static xfs_extlen_t
823+ xfs_internal_log_size (
824+ struct xfs_mount * mp )
826825{
827- struct xfs_mount * mp = XFS_M (dentry -> d_sb );
828- xfs_sb_t * sbp = & mp -> m_sb ;
829- struct xfs_inode * ip = XFS_I (d_inode (dentry ));
830- uint64_t fakeinos , id ;
831- uint64_t icount ;
832- uint64_t ifree ;
833- uint64_t fdblocks ;
834- xfs_extlen_t lsize ;
835- int64_t ffree ;
836-
837- /*
838- * Expedite background inodegc but don't wait. We do not want to block
839- * here waiting hours for a billion extent file to be truncated.
840- */
841- xfs_inodegc_push (mp );
842-
843- statp -> f_type = XFS_SUPER_MAGIC ;
844- statp -> f_namelen = MAXNAMELEN - 1 ;
845-
846- id = huge_encode_dev (mp -> m_ddev_targp -> bt_dev );
847- statp -> f_fsid = u64_to_fsid (id );
826+ if (!mp -> m_sb .sb_logstart )
827+ return 0 ;
828+ return mp -> m_sb .sb_logblocks ;
829+ }
848830
849- icount = percpu_counter_sum (& mp -> m_icount );
850- ifree = percpu_counter_sum (& mp -> m_ifree );
851- fdblocks = percpu_counter_sum (& mp -> m_fdblocks );
831+ static void
832+ xfs_statfs_data (
833+ struct xfs_mount * mp ,
834+ struct kstatfs * st )
835+ {
836+ int64_t fdblocks =
837+ percpu_counter_sum (& mp -> m_fdblocks );
852838
853- statp -> f_bsize = sbp -> sb_blocksize ;
854- lsize = sbp -> sb_logstart ? sbp -> sb_logblocks : 0 ;
839+ /* make sure st->f_bfree does not underflow */
840+ st -> f_bfree = max ( 0LL , fdblocks - xfs_fdblocks_unavailable ( mp )) ;
855841 /*
856842 * sb_dblocks can change during growfs, but nothing cares about reporting
857843 * the old or new value during growfs.
858844 */
859- statp -> f_blocks = sbp -> sb_dblocks - lsize ;
845+ st -> f_blocks = mp -> m_sb .sb_dblocks - xfs_internal_log_size (mp );
846+ }
847+
848+ /*
849+ * When stat(v)fs is called on a file with the realtime bit set or a directory
850+ * with the rtinherit bit, report freespace information for the RT device
851+ * instead of the main data device.
852+ */
853+ static void
854+ xfs_statfs_rt (
855+ struct xfs_mount * mp ,
856+ struct kstatfs * st )
857+ {
858+ st -> f_bfree = xfs_rtbxlen_to_blen (mp ,
859+ percpu_counter_sum_positive (& mp -> m_frextents ));
860+ st -> f_blocks = mp -> m_sb .sb_rblocks ;
861+ }
860862
861- /* make sure statp->f_bfree does not underflow */
862- statp -> f_bfree = max_t (int64_t , 0 ,
863- fdblocks - xfs_fdblocks_unavailable (mp ));
864- statp -> f_bavail = statp -> f_bfree ;
863+ static void
864+ xfs_statfs_inodes (
865+ struct xfs_mount * mp ,
866+ struct kstatfs * st )
867+ {
868+ uint64_t icount = percpu_counter_sum (& mp -> m_icount );
869+ uint64_t ifree = percpu_counter_sum (& mp -> m_ifree );
870+ uint64_t fakeinos = XFS_FSB_TO_INO (mp , st -> f_bfree );
865871
866- fakeinos = XFS_FSB_TO_INO (mp , statp -> f_bfree );
867- statp -> f_files = min (icount + fakeinos , (uint64_t )XFS_MAXINUMBER );
872+ st -> f_files = min (icount + fakeinos , (uint64_t )XFS_MAXINUMBER );
868873 if (M_IGEO (mp )-> maxicount )
869- statp -> f_files = min_t (typeof (statp -> f_files ),
870- statp -> f_files ,
874+ st -> f_files = min_t (typeof (st -> f_files ), st -> f_files ,
871875 M_IGEO (mp )-> maxicount );
872876
873877 /* If sb_icount overshot maxicount, report actual allocation */
874- statp -> f_files = max_t (typeof (statp -> f_files ),
875- statp -> f_files ,
876- sbp -> sb_icount );
878+ st -> f_files = max_t (typeof (st -> f_files ), st -> f_files ,
879+ mp -> m_sb .sb_icount );
877880
878- /* make sure statp ->f_ffree does not underflow */
879- ffree = statp -> f_files - (icount - ifree );
880- statp -> f_ffree = max_t ( int64_t , ffree , 0 );
881+ /* Make sure st ->f_ffree does not underflow */
882+ st -> f_ffree = max_t ( int64_t , 0 , st -> f_files - (icount - ifree ) );
883+ }
881884
882- if (XFS_IS_REALTIME_MOUNT (mp ) &&
883- (ip -> i_diflags & (XFS_DIFLAG_RTINHERIT | XFS_DIFLAG_REALTIME ))) {
884- s64 freertx ;
885+ STATIC int
886+ xfs_fs_statfs (
887+ struct dentry * dentry ,
888+ struct kstatfs * st )
889+ {
890+ struct xfs_mount * mp = XFS_M (dentry -> d_sb );
891+ struct xfs_inode * ip = XFS_I (d_inode (dentry ));
885892
886- statp -> f_blocks = sbp -> sb_rblocks ;
887- freertx = percpu_counter_sum_positive (& mp -> m_frextents );
888- statp -> f_bavail = statp -> f_bfree =
889- xfs_rtbxlen_to_blen (mp , freertx );
890- }
893+ /*
894+ * Expedite background inodegc but don't wait. We do not want to block
895+ * here waiting hours for a billion extent file to be truncated.
896+ */
897+ xfs_inodegc_push (mp );
898+
899+ st -> f_type = XFS_SUPER_MAGIC ;
900+ st -> f_namelen = MAXNAMELEN - 1 ;
901+ st -> f_bsize = mp -> m_sb .sb_blocksize ;
902+ st -> f_fsid = u64_to_fsid (huge_encode_dev (mp -> m_ddev_targp -> bt_dev ));
903+
904+ xfs_statfs_data (mp , st );
905+ xfs_statfs_inodes (mp , st );
906+
907+ if (XFS_IS_REALTIME_MOUNT (mp ) &&
908+ (ip -> i_diflags & (XFS_DIFLAG_RTINHERIT | XFS_DIFLAG_REALTIME )))
909+ xfs_statfs_rt (mp , st );
891910
892911 if ((ip -> i_diflags & XFS_DIFLAG_PROJINHERIT ) &&
893912 ((mp -> m_qflags & (XFS_PQUOTA_ACCT |XFS_PQUOTA_ENFD ))) ==
894913 (XFS_PQUOTA_ACCT |XFS_PQUOTA_ENFD ))
895- xfs_qm_statvfs (ip , statp );
914+ xfs_qm_statvfs (ip , st );
896915
916+ /*
917+ * XFS does not distinguish between blocks available to privileged and
918+ * unprivileged users.
919+ */
920+ st -> f_bavail = st -> f_bfree ;
897921 return 0 ;
898922}
899923
0 commit comments