aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2021-02-20 13:15:55 -0800
committerRob Landley <rob@landley.net>2021-02-20 17:31:32 -0600
commit47b9f6a12d471086ceb11c8e2893450074e50543 (patch)
treed263b9995388463003a80fe3d2396a1e4a12f950
parente6207d5e0f42452e96c66a9173b3d17468629beb (diff)
downloadtoybox-47b9f6a12d471086ceb11c8e2893450074e50543.tar.gz
Fix df on macOS.
On Linux, struct statvfs' f_bsize and f_frsize seem to be interchangeable. On macOS, they're wildly different. f_bsize is the "preferred length of I/O requests for files on this file system" (corresponding to statfs::f_iosize), and f_frsize is the "size in bytes of the minimum unit of allocation on this file system" (corresponding to statfs::f_bsize. POSIX appears to say nothing about the interpretation of these fields, but man7.org's statvfs(2) page is quite clear that statvfs::f_blocks, for example, is in units of f_frsize, not f_bsize. This is the only place in the tree where we use statvfs::f_bsize (other than the stat(1) output that's supposed to be f_bsize and that has a corresponding f_frsize dual anyway. I've removed the Apple-specific #define f_frsize in portability.h because that seems to have been from my previous attempt to understand what was going on here. The output of the relevant stat(1) fields on macOS are the same before/after this patch. This makes toybox df's output match the system's df on a MacBook Pro running macOS 11.2.1. Tested on a Raspberry Pi 400 running Linux too, where I see no change in the output before/after this patch.
-rw-r--r--lib/portability.h4
-rw-r--r--toys/posix/df.c2
2 files changed, 1 insertions, 5 deletions
diff --git a/lib/portability.h b/lib/portability.h
index bbba12d8..b3646473 100644
--- a/lib/portability.h
+++ b/lib/portability.h
@@ -346,10 +346,6 @@ struct xnotify *xnotify_init(int max);
int xnotify_add(struct xnotify *not, int fd, char *path);
int xnotify_wait(struct xnotify *not, char **path);
-#ifdef __APPLE__
-#define f_frsize f_iosize
-#endif
-
int sig_to_num(char *s);
char *num_to_sig(int sig);
diff --git a/toys/posix/df.c b/toys/posix/df.c
index c8f492ea..0520923e 100644
--- a/toys/posix/df.c
+++ b/toys/posix/df.c
@@ -102,7 +102,7 @@ static void show_mt(struct mtab_list *mt, int measuring)
suap[1] = mt->statvfs.f_files - mt->statvfs.f_ffree;
suap[2] = getuid() ? mt->statvfs.f_favail : mt->statvfs.f_ffree;
} else {
- block = maxof(mt->statvfs.f_bsize, 1);
+ block = maxof(mt->statvfs.f_frsize, 1);
suap[0] = mt->statvfs.f_blocks;
suap[1] = mt->statvfs.f_blocks - mt->statvfs.f_bfree;
suap[2] = getuid() ? mt->statvfs.f_bavail : mt->statvfs.f_bfree;