linux(4): Rework statfs conversion routine.
Rework the routines to convert a native statfs structure (with fixed-size 64-bit
counters) to a Linux statfs structure (with long-sized counters) for 32-bit apps.
Instead of following Linux and return an EOVERFLOW error from statfs() family of
syscalls when actual fs stat value(s) are large enough to not fit into 32 bits,
apply scale logics used by FreeBSD to convert a 5.x statfs structure to a 4.x
statfs structure.
For more details see cc479dda
.
Tested by: glebius
MFC after: 1 week
This commit is contained in:
parent
4d77927e2a
commit
953688e823
@ -413,26 +413,22 @@ bsd_to_linux_ftype(const char *fstypename)
|
||||
static int
|
||||
bsd_to_linux_statfs(struct statfs *bsd_statfs, struct l_statfs *linux_statfs)
|
||||
{
|
||||
|
||||
#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
|
||||
uint64_t tmp;
|
||||
|
||||
#define LINUX_HIBITS 0xffffffff00000000ULL
|
||||
|
||||
tmp = bsd_statfs->f_blocks | bsd_statfs->f_bfree | bsd_statfs->f_files |
|
||||
bsd_statfs->f_bsize;
|
||||
if ((bsd_statfs->f_bavail != -1 && (bsd_statfs->f_bavail & LINUX_HIBITS)) ||
|
||||
(bsd_statfs->f_ffree != -1 && (bsd_statfs->f_ffree & LINUX_HIBITS)) ||
|
||||
(tmp & LINUX_HIBITS))
|
||||
return (EOVERFLOW);
|
||||
#undef LINUX_HIBITS
|
||||
statfs_scale_blocks(bsd_statfs, INT32_MAX);
|
||||
#endif
|
||||
linux_statfs->f_type = bsd_to_linux_ftype(bsd_statfs->f_fstypename);
|
||||
linux_statfs->f_bsize = bsd_statfs->f_bsize;
|
||||
linux_statfs->f_blocks = bsd_statfs->f_blocks;
|
||||
linux_statfs->f_bfree = bsd_statfs->f_bfree;
|
||||
linux_statfs->f_bavail = bsd_statfs->f_bavail;
|
||||
#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
|
||||
linux_statfs->f_ffree = MIN(bsd_statfs->f_ffree, INT32_MAX);
|
||||
linux_statfs->f_files = MIN(bsd_statfs->f_files, INT32_MAX);
|
||||
#else
|
||||
linux_statfs->f_ffree = bsd_statfs->f_ffree;
|
||||
linux_statfs->f_files = bsd_statfs->f_files;
|
||||
#endif
|
||||
linux_statfs->f_fsid.val[0] = bsd_statfs->f_fsid.val[0];
|
||||
linux_statfs->f_fsid.val[1] = bsd_statfs->f_fsid.val[1];
|
||||
linux_statfs->f_namelen = MAXNAMLEN;
|
||||
|
Loading…
Reference in New Issue
Block a user