From 6567db65f495cf7c11f5c1e60a3e54543d5a69bc Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 19 Jul 2013 02:48:18 -0400 Subject: [PATCH] improve [f]stat[v]fs functions, and possibly work around old kernels the main aim of this patch is to ensure that if not all fields are filled in, they contain zeros, so as not to confuse applications. reportedly some older kernels, including commonly used openvz kernels, lack the f_flags field, resulting in applications reading random junk as the mount flags; the common symptom seems to be wrongly considering the filesystem to be mounted read-only and refusing to operate. glibc has some amazingly ugly fallback code to get the mount flags for old kernels, but having them really is not that important anyway; what matters most is not presenting incorrect flags to the application. I have also aimed to fill in some fields of statvfs that were previously missing, and added code to explicitly zero the reserved space at the end of the structure, which will make things easier in the future if this space someday needs to be used. --- src/stat/statvfs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/stat/statvfs.c b/src/stat/statvfs.c index 637bf82f..30d58797 100644 --- a/src/stat/statvfs.c +++ b/src/stat/statvfs.c @@ -5,6 +5,7 @@ int __statfs(const char *path, struct statfs *buf) { + *buf = (struct statfs){0}; #ifdef SYS_statfs64 return syscall(SYS_statfs64, path, sizeof *buf, buf); #else @@ -14,6 +15,7 @@ int __statfs(const char *path, struct statfs *buf) int __fstatfs(int fd, struct statfs *buf) { + *buf = (struct statfs){0}; #ifdef SYS_fstatfs64 return syscall(SYS_fstatfs64, fd, sizeof *buf, buf); #else @@ -26,14 +28,15 @@ weak_alias(__fstatfs, fstatfs); static void fixup(struct statvfs *out, const struct statfs *in) { + *out = (struct statvfs){0}; out->f_bsize = in->f_bsize; - out->f_frsize = in->f_bsize; + out->f_frsize = in->f_frsize ? in->f_frsize : in->f_bsize; out->f_blocks = in->f_blocks; out->f_bfree = in->f_bfree; out->f_bavail = in->f_bavail; out->f_files = in->f_files; out->f_ffree = in->f_ffree; - out->f_favail = 0; + out->f_favail = in->f_ffree; out->f_fsid = in->f_fsid.__val[0]; out->f_flag = in->f_flags; out->f_namemax = in->f_namelen; -- 2.25.1