From: Matthew Dillon Date: Thu, 25 Jun 2009 19:50:50 +0000 (-0700) Subject: HAMMER VFS - Take reserved space into account when reporting statvfs data X-Git-Tag: v2.3.2~102 X-Git-Url: http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/0f65be104647b75aea01cc199143fba6a0063982 HAMMER VFS - Take reserved space into account when reporting statvfs data 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 (with modification) --- diff --git a/sys/vfs/hammer/hammer.h b/sys/vfs/hammer/hammer.h index c9051e2..d1c72ad 100644 --- a/sys/vfs/hammer/hammer.h +++ b/sys/vfs/hammer/hammer.h @@ -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 diff --git a/sys/vfs/hammer/hammer_blockmap.c b/sys/vfs/hammer/hammer_blockmap.c index 6208335..ef77d72 100644 --- a/sys/vfs/hammer/hammer_blockmap.c +++ b/sys/vfs/hammer/hammer_blockmap.c @@ -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)) { diff --git a/sys/vfs/hammer/hammer_vfsops.c b/sys/vfs/hammer/hammer_vfsops.c index 772958b..61e765e 100644 --- a/sys/vfs/hammer/hammer_vfsops.c +++ b/sys/vfs/hammer/hammer_vfsops.c @@ -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;