1 /* fsusage.c -- return space usage of mounted filesystems
2 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include <sys/types.h>
29 # include <sys/param.h>
33 # include <sys/mount.h>
40 #if HAVE_SYS_FS_S5PARAM_H /* Fujitsu UXP/V */
41 # include <sys/fs/s5param.h>
44 #if defined (HAVE_SYS_FILSYS_H) && !defined (_CRAY)
45 # include <sys/filsys.h> /* SVR2 */
53 # include <sys/statfs.h>
56 #if HAVE_DUSTAT_H /* AIX PS/2 */
57 # include <sys/dustat.h>
60 #if HAVE_SYS_STATVFS_H /* SVR4 */
61 # include <sys/statvfs.h>
67 /* Return the number of TOSIZE-byte blocks used by
68 BLOCKS FROMSIZE-byte blocks, rounding away from zero.
69 TOSIZE must be positive. Return -1 if FROMSIZE is not positive. */
72 adjust_blocks (blocks
, fromsize
, tosize
)
81 if (fromsize
== tosize
) /* e.g., from 512 to 512 */
83 else if (fromsize
> tosize
) /* e.g., from 2048 to 512 */
84 return blocks
* (fromsize
/ tosize
);
85 else /* e.g., from 256 to 512 */
86 return (blocks
+ (blocks
< 0 ? -1 : 1)) / (tosize
/ fromsize
);
89 /* Fill in the fields of FSP with information about space usage for
90 the filesystem on which PATH resides.
91 DISK is the device on which PATH is mounted, for space-getting
92 methods that need to know it.
93 Return 0 if successful, -1 if not. */
96 get_fs_usage (path
, disk
, fsp
)
101 #ifdef STAT_STATFS3_OSF1
102 # define CONVERT_BLOCKS(B) adjust_blocks ((B), fsd.f_fsize, 512)
106 if (statfs (path
, &fsd
, sizeof (struct statfs
)) != 0)
109 #endif /* STAT_STATFS3_OSF1 */
111 #ifdef STAT_STATFS2_FS_DATA /* Ultrix */
112 # define CONVERT_BLOCKS(B) adjust_blocks ((B), 1024, 512)
116 if (statfs (path
, &fsd
) != 1)
118 fsp
->fsu_blocks
= CONVERT_BLOCKS (fsd
.fd_req
.btot
);
119 fsp
->fsu_bfree
= CONVERT_BLOCKS (fsd
.fd_req
.bfree
);
120 fsp
->fsu_bavail
= CONVERT_BLOCKS (fsd
.fd_req
.bfreen
);
121 fsp
->fsu_files
= fsd
.fd_req
.gtot
;
122 fsp
->fsu_ffree
= fsd
.fd_req
.gfree
;
124 #endif /* STAT_STATFS2_FS_DATA */
126 #ifdef STAT_READ_FILSYS /* SVR2 */
128 # define SUPERBOFF (SUPERB * 512)
130 # define CONVERT_BLOCKS(B) \
131 adjust_blocks ((B), (fsd.s_type == Fs2b ? 1024 : 512), 512)
136 fd
= open (disk
, O_RDONLY
);
139 lseek (fd
, (long) SUPERBOFF
, 0);
140 if (safe_read (fd
, (char *) &fsd
, sizeof fsd
) != sizeof fsd
)
146 fsp
->fsu_blocks
= CONVERT_BLOCKS (fsd
.s_fsize
);
147 fsp
->fsu_bfree
= CONVERT_BLOCKS (fsd
.s_tfree
);
148 fsp
->fsu_bavail
= CONVERT_BLOCKS (fsd
.s_tfree
);
149 fsp
->fsu_files
= (fsd
.s_isize
- 2) * INOPB
* (fsd
.s_type
== Fs2b
? 2 : 1);
150 fsp
->fsu_ffree
= fsd
.s_tinode
;
152 #endif /* STAT_READ_FILSYS */
154 #ifdef STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX */
155 # define CONVERT_BLOCKS(B) adjust_blocks ((B), fsd.f_bsize, 512)
159 if (statfs (path
, &fsd
) < 0)
162 # ifdef STATFS_TRUNCATES_BLOCK_COUNTS
164 /* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the
165 struct statfs are truncated to 2GB. These conditions detect that
166 truncation, presumably without botching the 4.1.1 case, in which
167 the values are not truncated. The correct counts are stored in
168 undocumented spare fields. */
169 if (fsd
.f_blocks
== 0x1fffff && fsd
.f_spare
[0] > 0)
171 fsd
.f_blocks
= fsd
.f_spare
[0];
172 fsd
.f_bfree
= fsd
.f_spare
[1];
173 fsd
.f_bavail
= fsd
.f_spare
[2];
175 # endif /* STATFS_TRUNCATES_BLOCK_COUNTS */
177 #endif /* STAT_STATFS2_BSIZE */
179 #ifdef STAT_STATFS2_FSIZE /* 4.4BSD */
180 # define CONVERT_BLOCKS(B) adjust_blocks ((B), fsd.f_fsize, 512)
184 if (statfs (path
, &fsd
) < 0)
187 #endif /* STAT_STATFS2_FSIZE */
189 #ifdef STAT_STATFS4 /* SVR3, Dynix, Irix, AIX */
190 # if _AIX || defined(_CRAY)
191 # define CONVERT_BLOCKS(B) adjust_blocks ((B), fsd.f_bsize, 512)
193 # define f_bavail f_bfree
196 # define CONVERT_BLOCKS(B) (B)
197 # ifndef _SEQUENT_ /* _SEQUENT_ is DYNIX/ptx */
198 # ifndef DOLPHIN /* DOLPHIN 3.8.alfa/7.18 has f_bavail */
199 # define f_bavail f_bfree
206 if (statfs (path
, &fsd
, sizeof fsd
, 0) < 0)
208 /* Empirically, the block counts on most SVR3 and SVR3-derived
209 systems seem to always be in terms of 512-byte blocks,
210 no matter what value f_bsize has. */
212 #endif /* STAT_STATFS4 */
214 #ifdef STAT_STATVFS /* SVR4 */
215 # define CONVERT_BLOCKS(B) \
216 adjust_blocks ((B), fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize, 512)
220 if (statvfs (path
, &fsd
) < 0)
222 /* f_frsize isn't guaranteed to be supported. */
224 #endif /* STAT_STATVFS */
226 #if !defined(STAT_STATFS2_FS_DATA) && !defined(STAT_READ_FILSYS)
227 /* !Ultrix && !SVR2 */
229 fsp
->fsu_blocks
= CONVERT_BLOCKS (fsd
.f_blocks
);
230 fsp
->fsu_bfree
= CONVERT_BLOCKS (fsd
.f_bfree
);
231 fsp
->fsu_bavail
= CONVERT_BLOCKS (fsd
.f_bavail
);
232 fsp
->fsu_files
= fsd
.f_files
;
233 fsp
->fsu_ffree
= fsd
.f_ffree
;
235 #endif /* not STAT_STATFS2_FS_DATA && not STAT_READ_FILSYS */
240 #if defined(_AIX) && defined(_I386)
241 /* AIX PS/2 does not supply statfs. */
251 if (stat (path
, &stats
))
253 if (dustat (stats
.st_dev
, 0, &fsd
, sizeof (fsd
)))
256 fsb
->f_bsize
= fsd
.du_bsize
;
257 fsb
->f_blocks
= fsd
.du_fsize
- fsd
.du_isize
;
258 fsb
->f_bfree
= fsd
.du_tfree
;
259 fsb
->f_bavail
= fsd
.du_tfree
;
260 fsb
->f_files
= (fsd
.du_isize
- 2) * fsd
.du_inopb
;
261 fsb
->f_ffree
= fsd
.du_tinode
;
262 fsb
->f_fsid
.val
[0] = fsd
.du_site
;
263 fsb
->f_fsid
.val
[1] = fsd
.du_pckno
;
267 #endif /* _AIX && _I386 */