Bug 71898 - rpm doesn't handle large file systems gracefully
Summary: rpm doesn't handle large file systems gracefully
Keywords:
Status: CLOSED DEFERRED
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: rpm
Version: 7.3
Hardware: i386
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Jeff Johnson
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2002-08-20 02:44 UTC by Ben Woodard
Modified: 2008-05-01 15:38 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2002-08-20 02:44:53 UTC
Embargoed:


Attachments (Terms of Use)

Description Ben Woodard 2002-08-20 02:44:49 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020606

Description of problem:
When you have a file system with about 1TB available RPM doesn't compute the
amount of space available correctly. No matter how much disk space you have
available it aborts with the warning:

installing package "any_package" needs 3125Mb on the /p/ba1 filesystem



Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
1.Mount up a file system with huge amounts of available disk space i.e. 1 TB or
greater.
2.Try to install an RPM without the --ignoresize option

	

Actual Results:  installing package "any_package" needs 3125Mb on the /p/ba1
filesystem

Expected Results:  the package installs.

Additional info:

This appears to be a problem with RPM's diskspaceInfo structure. The
diskspaceInfo structure uses signed longs to represent the available blocks but
fsstat returns either unsigned longs or unsigned long longs.

if you look in lib/transaction.c:

    52  struct diskspaceInfo {
    53      dev_t dev;                  /*!< file system device number. */
    54      signed long bneeded;        /*!< no. of blocks needed. */
    55      signed long ineeded;        /*!< no. of inodes needed. */
    56      int bsize;                  /*!< file system block size. */
    57      signed long bavail;         /*!< no. of blocks available. */
    58      signed long iavail;         /*!< no. of inodes available. */
    59  };

and then compare it with what you see in /usr/include/bits/statfs.h:

    25  struct statfs
    26    {
    27      int f_type;
    28      int f_bsize;
    29  #ifndef __USE_FILE_OFFSET64
    30      __fsblkcnt_t f_blocks;
    31      __fsblkcnt_t f_bfree;
    32      __fsblkcnt_t f_bavail;
    33      __fsfilcnt_t f_files;
    34      __fsfilcnt_t f_ffree;
    35  #else
    36      __fsblkcnt64_t f_blocks;
    37      __fsblkcnt64_t f_bfree;
    38      __fsblkcnt64_t f_bavail;
    39      __fsfilcnt64_t f_files;
    40      __fsfilcnt64_t f_ffree;
    41  #endif
    42      __fsid_t f_fsid;
    43      int f_namelen;
    44      int f_spare[6];
    45    };

and in /usr/include/bits/types.h:

   116  /* Type to count file system blocks.  */
   117  typedef __u_long __fsblkcnt_t;
   118  typedef __u_quad_t __fsblkcnt64_t;

a confounding problem is that the statfs man page is wrong:

NAME
       statfs, fstatfs - get file system statistics

SYNOPSIS
       #include <sys/vfs.h>

       int statfs(const char *path, struct statfs *buf);
       int fstatfs(int fd, struct statfs *buf);

DESCRIPTION
       statfs  returns  information  about a mounted file system.
       path is the path name  of  any  file  within  the  mounted
       filesystem.   buf  is  a  pointer  to  a  statfs structure
       defined as follows:

              struct statfs {
                 long    f_type;     /* type of filesystem (see below) */
                 long    f_bsize;    /* optimal transfer block size */
                 long    f_blocks;   /* total data blocks in file system */
                 long    f_bfree;    /* free blocks in fs */
                 long    f_bavail;   /* free blocks avail to non-superuser */
                 long    f_files;    /* total file nodes in file system */
                 long    f_ffree;    /* free file nodes in fs */
                 fsid_t  f_fsid;     /* file system id */
                 long    f_namelen;  /* maximum length of filenames */
                 long    f_spare[6]; /* spare for later */
              };

...

Comment 1 Jeff Johnson 2002-08-20 16:17:33 UTC
Yup, struct diskspaceInfo was written from the man page.

Deferred until I see my 1st TB file system :-)


Note You need to log in before you can comment on or make changes to this bug.