Skip to content

Make sure that statvfs is used correctly #116642

Open
@sobolevn

Description

@sobolevn

Bug report

While working on #116542 @serhiy-storchaka noticed that

Also, on Linux some of fields are defined as unsigned long instead of long. Did not check other Posix systems. There may be a problem, but this is another issue.

Here's how it is documented:

struct statvfs {
               unsigned long  f_bsize;    /* Filesystem block size */
               unsigned long  f_frsize;   /* Fragment size */
               fsblkcnt_t     f_blocks;   /* Size of fs in f_frsize units */
               fsblkcnt_t     f_bfree;    /* Number of free blocks */
               fsblkcnt_t     f_bavail;   /* Number of free blocks for
                                             unprivileged users */
               fsfilcnt_t     f_files;    /* Number of inodes */
               fsfilcnt_t     f_ffree;    /* Number of free inodes */
               fsfilcnt_t     f_favail;   /* Number of free inodes for
                                             unprivileged users */
               unsigned long  f_fsid;     /* Filesystem ID */
               unsigned long  f_flag;     /* Mount flags */
               unsigned long  f_namemax;  /* Maximum filename length */
           };

Here's how it is used:

cpython/Modules/posixmodule.c

Lines 12983 to 13011 in d308d33

#if !defined(HAVE_LARGEFILE_SUPPORT)
PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
#else
PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
PyStructSequence_SET_ITEM(v, 2,
PyLong_FromLongLong((long long) st.f_blocks));
PyStructSequence_SET_ITEM(v, 3,
PyLong_FromLongLong((long long) st.f_bfree));
PyStructSequence_SET_ITEM(v, 4,
PyLong_FromLongLong((long long) st.f_bavail));
PyStructSequence_SET_ITEM(v, 5,
PyLong_FromLongLong((long long) st.f_files));
PyStructSequence_SET_ITEM(v, 6,
PyLong_FromLongLong((long long) st.f_ffree));
PyStructSequence_SET_ITEM(v, 7,
PyLong_FromLongLong((long long) st.f_favail));
PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
#endif

Notice that f_bsize is documented to be unsigned long, but it treated as long:

PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));

This might be a problem.

Here' git blame for these lines:

» git blame -L 12983,+30 -- Modules/posixmodule.c
Blaming lines: 100% (30/30), done.
98bf58f1c61a (Guido van Rossum  2001-10-18 20:34:25 +0000 12983) #if !defined(HAVE_LARGEFILE_SUPPORT)
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12984)     PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12985)     PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12986)     PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12987)     PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12988)     PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12989)     PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12990)     PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12991)     PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12992)     PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12993)     PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
98bf58f1c61a (Guido van Rossum  2001-10-18 20:34:25 +0000 12994) #else
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12995)     PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12996)     PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12997)     PyStructSequence_SET_I
TEM(v, 2,
af580dff4af3 (Benjamin Peterson 2016-09-06 10:46:49 -0700 12998)                           
    PyLong_FromLongLong((long long) st.f_blocks));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 12999)     PyStructSequence_SET_I
TEM(v, 3,
af580dff4af3 (Benjamin Peterson 2016-09-06 10:46:49 -0700 13000)                           
    PyLong_FromLongLong((long long) st.f_bfree));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 13001)     PyStructSequence_SET_I
TEM(v, 4,
af580dff4af3 (Benjamin Peterson 2016-09-06 10:46:49 -0700 13002)                           
    PyLong_FromLongLong((long long) st.f_bavail));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 13003)     PyStructSequence_SET_I
TEM(v, 5,
af580dff4af3 (Benjamin Peterson 2016-09-06 10:46:49 -0700 13004)                           
    PyLong_FromLongLong((long long) st.f_files));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 13005)     PyStructSequence_SET_I
TEM(v, 6,
af580dff4af3 (Benjamin Peterson 2016-09-06 10:46:49 -0700 13006)                           
    PyLong_FromLongLong((long long) st.f_ffree));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 13007)     PyStructSequence_SET_I
TEM(v, 7,
af580dff4af3 (Benjamin Peterson 2016-09-06 10:46:49 -0700 13008)                           
    PyLong_FromLongLong((long long) st.f_favail));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 13009)     PyStructSequence_SET_I
TEM(v, 8, PyLong_FromLong((long) st.f_flag));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 13010)     PyStructSequence_SET_I
TEM(v, 9, PyLong_FromLong((long) st.f_namemax));
8c62be88e6d5 (Victor Stinner    2010-05-06 00:08:46 +0000 13011) #endif
502d551c6d78 (Michael Felt      2018-01-05 13:01:58 +0100 13012) /* The _ALL_SOURCE feature
 test macro defines f_fsid as a structure

On the other hand, seems like this code was there for a very long time, with seemingly no issues. Maybe there are some platform differences that we need to remember about.

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions