]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - estimate/xfs_estimate.c
65b7168d92345d9d85c66a09fa5eb49d9ef75cf6
2 * Copyright (c) 2000-2002 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would 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 the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * Estimate space of an XFS filesystem
22 * XXX: assumes dirv1 format.
34 i
= strtoll(s
, &sp
, 0);
35 if (i
== 0 && sp
== s
)
39 if (*sp
=='k' && sp
[1] == '\0')
41 if (*sp
=='m' && sp
[1] == '\0')
42 return 1024LL * 1024LL * i
;
43 if (*sp
=='g' && sp
[1] == '\0')
44 return 1024LL * 1024LL * 1024LL * i
;
48 int ffn(const char *, const struct stat64
*, int, struct FTW
*);
50 #define BLOCKSIZE 4096
53 (sizeof(xfs_dir2_leaf_entry_t) + sizeof(xfs_dir2_data_entry_t))
56 #define FBLOCKS(n) ((n)/blocksize)
57 #define RFBYTES(n) ((n) - (FBLOCKS(n) * blocksize))
59 unsigned long long dirsize
=0; /* bytes */
60 unsigned long long logsize
=LOGSIZE
*BLOCKSIZE
; /* bytes */
61 unsigned long long fullblocks
=0; /* FS blocks */
62 unsigned long long isize
=0; /* inodes bytes */
63 unsigned long long blocksize
=BLOCKSIZE
;
64 unsigned long long nslinks
=0; /* number of symbolic links */
65 unsigned long long nfiles
=0; /* number of regular files */
66 unsigned long long ndirs
=0; /* number of directories */
67 unsigned long long nspecial
=0; /* number of special files */
68 unsigned long long verbose
=0; /* verbose mode TRUE/FALSE */
78 _("Usage: %s [opts] directory [directory ...]\n"
79 "\t-b blocksize (fundamental filesystem blocksize)\n"
80 "\t-i logsize (internal log size)\n"
81 "\t-e logsize (external log size)\n"
82 "\t-v prints more verbose messages\n"
83 "\t-V prints version and exits\n"
84 "\t-h prints this usage message\n\n"
85 "Note:\tblocksize may have 'k' appended to indicate x1024\n"
86 "\tlogsize may also have 'm' appended to indicate (1024 x 1024)\n"),
92 main(int argc
, char **argv
)
94 unsigned long long est
;
100 setlocale(LC_ALL
, "");
101 bindtextdomain(PACKAGE
, LOCALEDIR
);
104 while ((c
= getopt (argc
, argv
, "b:hdve:i:V")) != EOF
) {
107 blocksize
=cvtnum(optarg
);
108 if (blocksize
<= 0LL) {
109 fprintf(stderr
, _("blocksize %llu too small\n"),
113 else if (blocksize
> 64LL * 1024LL) {
114 fprintf(stderr
, _("blocksize %llu too large\n"),
121 fprintf(stderr
, _("already have external log "
122 "noted, can't have both\n"));
125 logsize
=cvtnum(optarg
);
130 fprintf(stderr
, _("already have internal log "
131 "noted, can't have both\n"));
134 logsize
=cvtnum(optarg
);
144 printf(_("%s version %s\n"), basename(argv
[0]), VERSION
);
155 if (!elog
&& !ilog
) {
157 logsize
=LOGSIZE
* blocksize
;
160 printf(_("directory bsize blocks megabytes logsize\n"));
162 for ( ; optind
< argc
; optind
++) {
163 dirsize
=0LL; /* bytes */
164 fullblocks
=0LL; /* FS blocks */
165 isize
=0LL; /* inodes bytes */
166 nslinks
=0LL; /* number of symbolic links */
167 nfiles
=0LL; /* number of regular files */
168 ndirs
=0LL; /* number of directories */
169 nspecial
=0LL; /* number of special files */
171 nftw64(argv
[optind
], ffn
, 40, FTW_PHYS
| FTW_MOUNT
);
174 printf(_("dirsize=%llu\n"), dirsize
);
175 printf(_("fullblocks=%llu\n"), fullblocks
);
176 printf(_("isize=%llu\n"), isize
);
178 printf(_("%llu regular files\n"), nfiles
);
179 printf(_("%llu symbolic links\n"), nslinks
);
180 printf(_("%llu directories\n"), ndirs
);
181 printf(_("%llu special files\n"), nspecial
);
184 est
= FBLOCKS(isize
) + 8 /* blocks for inodes */
185 + FBLOCKS(dirsize
) + 1 /* blocks for directories */
186 + fullblocks
/* blocks for file contents */
187 + (8 * 16) /* fudge for overhead blks (per ag) */
188 + FBLOCKS(isize
/ INODESIZE
); /* 1 byte/inode for map */
191 est
+= (logsize
/ blocksize
);
194 printf(_("%s will take about %.1f megabytes\n"),
196 (double)est
*(double)blocksize
/(1024.0*1024.0));
198 /* avoid running over 39 characters in field */
199 strncpy(dname
, argv
[optind
], 40);
201 printf(_("%-39s %5llu %8llu %10.1fMB %10llu\n"),
202 dname
, blocksize
, est
,
203 (double)est
*(double)blocksize
/(1024.0*1024.0), logsize
);
206 if (!verbose
&& elog
) {
207 printf(_("\twith the external log using %llu blocks "),
209 printf(_("or about %.1f megabytes\n"),
210 (double)logsize
/(1024.0*1024.0));
217 ffn(const char *path
, const struct stat64
*stb
, int flags
, struct FTW
*f
)
219 /* cases are in most-encountered to least-encountered order */
220 dirsize
+=PERDIRENTRY
+strlen(path
);
222 switch (S_IFMT
& stb
->st_mode
) {
223 case S_IFREG
: /* regular files */
224 fullblocks
+=FBLOCKS(stb
->st_blocks
* 512 + blocksize
-1);
225 if (stb
->st_blocks
* 512 < stb
->st_size
)
226 fullblocks
++; /* add one bmap block here */
229 case S_IFLNK
: /* symbolic links */
230 if (stb
->st_size
>= (INODESIZE
- (sizeof(xfs_dinode_t
)+4)))
231 fullblocks
+=FBLOCKS(stb
->st_size
+ blocksize
-1);
234 case S_IFDIR
: /* directories */
235 dirsize
+=blocksize
; /* fudge upwards */
236 if (stb
->st_size
>= blocksize
)
240 case S_IFIFO
: /* named pipes */
241 case S_IFCHR
: /* Character Special device */
242 case S_IFBLK
: /* Block Special device */
243 case S_IFSOCK
: /* socket */