HAMMER VFS - Take reserved space into account when reporting statvfs data
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 25 Jun 2009 19:50:50 +0000 (12:50 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 25 Jun 2009 19:50:50 +0000 (12:50 -0700)
Adjust statvfs data so reserved space is taken into account, so the
filesystem starts failing modifying operations closer to when 'df' would
otherwise say that 0 free space remains.

Submitted-by: Antonio Huete Jimenez <tuxillo@quantumachine.net> (with modification)
sys/vfs/hammer/hammer.h
sys/vfs/hammer/hammer_blockmap.c
sys/vfs/hammer/hammer_vfsops.c

index c9051e2..d1c72ad 100644 (file)
@@ -1077,7 +1077,7 @@ hammer_off_t hammer_freemap_alloc(hammer_transaction_t trans,
                        hammer_off_t owner, int *errorp);
 void hammer_freemap_free(hammer_transaction_t trans, hammer_off_t phys_offset,
                        hammer_off_t owner, int *errorp);
-int hammer_checkspace(hammer_mount_t hmp, int slop);
+int _hammer_checkspace(hammer_mount_t hmp, int slop, int64_t *resp);
 hammer_off_t hammer_blockmap_alloc(hammer_transaction_t trans, int zone,
                        int bytes, hammer_off_t hint, int *errorp);
 hammer_reserve_t hammer_blockmap_reserve(hammer_mount_t hmp, int zone,
@@ -1246,6 +1246,15 @@ udev_t hammer_fsid_to_udev(uuid_t *uuid);
 int hammer_blocksize(int64_t file_offset);
 int64_t hammer_blockdemarc(int64_t file_offset1, int64_t file_offset2);
 
+/*
+ * Shortcut for _hammer_checkspace(), used all over the code.
+ */
+static __inline int
+hammer_checkspace(hammer_mount_t hmp, int slop)
+{
+       return(_hammer_checkspace(hmp, slop, NULL));
+}
+
 #endif
 
 static __inline void
index 6208335..ef77d72 100644 (file)
@@ -1187,7 +1187,7 @@ failed:
  * Check space availability
  */
 int
-hammer_checkspace(hammer_mount_t hmp, int slop)
+_hammer_checkspace(hammer_mount_t hmp, int slop, int64_t *resp)
 {
        const int in_size = sizeof(struct hammer_inode_data) +
                            sizeof(union hammer_btree_elm);
@@ -1202,6 +1202,8 @@ hammer_checkspace(hammer_mount_t hmp, int slop)
                    (slop << HAMMER_LARGEBLOCK_BITS);
 
        hammer_count_extra_space_used = usedbytes;      /* debugging */
+       if (resp)
+               *resp = usedbytes;
 
        if (hmp->copy_stat_freebigblocks >=
            (usedbytes >> HAMMER_LARGEBLOCK_BITS)) {
index 772958b..61e765e 100644 (file)
@@ -866,6 +866,7 @@ hammer_vfs_statvfs(struct mount *mp, struct statvfs *sbp, struct ucred *cred)
        hammer_volume_ondisk_t ondisk;
        int error;
        int64_t bfree;
+       int64_t breserved;
 
        volume = hammer_get_root_volume(hmp, &error);
        if (error)
@@ -875,11 +876,12 @@ hammer_vfs_statvfs(struct mount *mp, struct statvfs *sbp, struct ucred *cred)
        /*
         * Basic stats
         */
+       _hammer_checkspace(hmp, HAMMER_CHKSPC_WRITE, &breserved);
        mp->mnt_vstat.f_files = ondisk->vol0_stat_inodes;
        bfree = ondisk->vol0_stat_freebigblocks * HAMMER_LARGEBLOCK_SIZE;
        hammer_rel_volume(volume, 0);
 
-       mp->mnt_vstat.f_bfree = bfree / HAMMER_BUFSIZE;
+       mp->mnt_vstat.f_bfree = (bfree - breserved) / HAMMER_BUFSIZE;
        mp->mnt_vstat.f_bavail = mp->mnt_stat.f_bfree;
        if (mp->mnt_vstat.f_files < 0)
                mp->mnt_vstat.f_files = 0;