summaryrefslogtreecommitdiff
path: root/libc/misc/statfs/internal_statvfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/misc/statfs/internal_statvfs.c')
-rw-r--r--libc/misc/statfs/internal_statvfs.c112
1 files changed, 57 insertions, 55 deletions
diff --git a/libc/misc/statfs/internal_statvfs.c b/libc/misc/statfs/internal_statvfs.c
index 29890d490..717673921 100644
--- a/libc/misc/statfs/internal_statvfs.c
+++ b/libc/misc/statfs/internal_statvfs.c
@@ -16,6 +16,9 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+/* The kernel hints us if the f_flags is valid */
+#define ST_VALID 0x0020
+
/* Now fill in the fields we have information for. */
buf->f_bsize = fsbuf.f_bsize;
#ifdef _STATFS_F_FRSIZE
@@ -31,7 +34,7 @@
buf->f_ffree = fsbuf.f_ffree;
if (sizeof (buf->f_fsid) == sizeof (fsbuf.f_fsid))
buf->f_fsid = (fsbuf.f_fsid.__val[0]
- | ((unsigned long int) fsbuf.f_fsid.__val[1]
+ | ((unsigned long long int) fsbuf.f_fsid.__val[1]
<< (8 * (sizeof (buf->f_fsid)
- sizeof (fsbuf.f_fsid.__val[0])))));
else
@@ -43,9 +46,6 @@
#endif
buf->f_namemax = fsbuf.f_namelen;
memset (buf->__f_spare, '\0', sizeof(fsbuf.f_spare));
-
- /* What remains to do is to fill the fields f_favail and f_flag. */
-
/* XXX I have no idea how to compute f_favail. Any idea??? */
buf->f_favail = buf->f_ffree;
@@ -54,61 +54,63 @@
file. The way we can test for matching filesystem is using the
device number. */
buf->f_flag = 0;
- if (STAT (&st) >= 0)
- {
- int save_errno = errno;
- struct mntent mntbuf;
- FILE *mtab;
-
- mtab = setmntent ("/proc/mounts", "r");
- if (mtab == NULL)
- mtab = setmntent (_PATH_MOUNTED, "r");
+ if (STAT (&st) >= 0
+#ifdef _STATFS_F_FLAGS
+ && (fsbuf.f_flags & ST_VALID) == 0
+#endif
+ ) {
+ int save_errno = errno;
+ struct mntent mntbuf;
+ FILE *mtab;
- if (mtab != NULL)
- {
- char tmpbuf[1024];
+ mtab = setmntent ("/proc/mounts", "r");
+ if (mtab == NULL)
+ mtab = setmntent (_PATH_MOUNTED, "r");
+ if (mtab != NULL) {
+ char tmpbuf[1024];
- while (getmntent_r (mtab, &mntbuf, tmpbuf, sizeof (tmpbuf)))
- {
- struct stat fsst;
+ while (getmntent_r (mtab, &mntbuf, tmpbuf, sizeof (tmpbuf))) {
+ struct stat fsst;
- /* Find out about the device the current entry is for. */
- if (stat (mntbuf.mnt_dir, &fsst) >= 0
- && st.st_dev == fsst.st_dev)
- {
- /* Bingo, we found the entry for the device FD is on.
- Now interpret the option string. */
- char *cp = mntbuf.mnt_opts;
- char *opt;
+ /* Find out about the device the current entry is for. */
+ if (stat (mntbuf.mnt_dir, &fsst) >= 0
+ && st.st_dev == fsst.st_dev) {
+ /* Bingo, we found the entry for the device FD is on.
+ Now interpret the option string. */
+ char *cp = mntbuf.mnt_opts;
+ char *opt;
- while ((opt = strsep (&cp, ",")) != NULL)
- if (strcmp (opt, "ro") == 0)
- buf->f_flag |= ST_RDONLY;
- else if (strcmp (opt, "nosuid") == 0)
- buf->f_flag |= ST_NOSUID;
+ while ((opt = strsep (&cp, ",")) != NULL)
+ if (strcmp (opt, "ro") == 0)
+ buf->f_flag |= ST_RDONLY;
+ else if (strcmp (opt, "nosuid") == 0)
+ buf->f_flag |= ST_NOSUID;
#ifdef __USE_GNU
- else if (strcmp (opt, "noexec") == 0)
- buf->f_flag |= ST_NOEXEC;
- else if (strcmp (opt, "nodev") == 0)
- buf->f_flag |= ST_NODEV;
- else if (strcmp (opt, "sync") == 0)
- buf->f_flag |= ST_SYNCHRONOUS;
- else if (strcmp (opt, "mand") == 0)
- buf->f_flag |= ST_MANDLOCK;
- else if (strcmp (opt, "noatime") == 0)
- buf->f_flag |= ST_NOATIME;
- else if (strcmp (opt, "nodiratime") == 0)
- buf->f_flag |= ST_NODIRATIME;
+ else if (strcmp (opt, "noexec") == 0)
+ buf->f_flag |= ST_NOEXEC;
+ else if (strcmp (opt, "nodev") == 0)
+ buf->f_flag |= ST_NODEV;
+ else if (strcmp (opt, "sync") == 0)
+ buf->f_flag |= ST_SYNCHRONOUS;
+ else if (strcmp (opt, "mand") == 0)
+ buf->f_flag |= ST_MANDLOCK;
+ else if (strcmp (opt, "noatime") == 0)
+ buf->f_flag |= ST_NOATIME;
+ else if (strcmp (opt, "nodiratime") == 0)
+ buf->f_flag |= ST_NODIRATIME;
+ else if (strcmp (opt, "relatime") == 0)
+ buf->f_flag |= ST_RELATIME;
#endif
-
- /* We can stop looking for more entries. */
- break;
+ /* We can stop looking for more entries. */
+ break;
+ }
}
- }
-
- /* Close the file. */
- endmntent (mtab);
- }
-
- __set_errno (save_errno);
- }
+ /* Close the file. */
+ endmntent (mtab);
+ }
+ __set_errno (save_errno);
+ }
+#ifdef _STATFS_F_FLAGS
+ else
+ buf->f_flag = fsbuf.f_flags ^ ST_VALID;
+#endif