@@ -819,81 +819,105 @@ xfs_fs_sync_fs(
819
819
return 0 ;
820
820
}
821
821
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 )
826
825
{
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
+ }
848
830
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 );
852
838
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 )) ;
855
841
/*
856
842
* sb_dblocks can change during growfs, but nothing cares about reporting
857
843
* the old or new value during growfs.
858
844
*/
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
+ }
860
862
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 );
865
871
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 );
868
873
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 ,
871
875
M_IGEO (mp )-> maxicount );
872
876
873
877
/* 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 );
877
880
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
+ }
881
884
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 ));
885
892
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 );
891
910
892
911
if ((ip -> i_diflags & XFS_DIFLAG_PROJINHERIT ) &&
893
912
((mp -> m_qflags & (XFS_PQUOTA_ACCT |XFS_PQUOTA_ENFD ))) ==
894
913
(XFS_PQUOTA_ACCT |XFS_PQUOTA_ENFD ))
895
- xfs_qm_statvfs (ip , statp );
914
+ xfs_qm_statvfs (ip , st );
896
915
916
+ /*
917
+ * XFS does not distinguish between blocks available to privileged and
918
+ * unprivileged users.
919
+ */
920
+ st -> f_bavail = st -> f_bfree ;
897
921
return 0 ;
898
922
}
899
923
0 commit comments