]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - estimate/xfs_estimate.c
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 #include <xfs/libxfs.h>
32 i
= strtoll(s
, &sp
, 0);
33 if (i
== 0 && sp
== s
)
37 if (*sp
=='k' && sp
[1] == '\0')
39 if (*sp
=='m' && sp
[1] == '\0')
40 return 1024LL * 1024LL * i
;
41 if (*sp
=='g' && sp
[1] == '\0')
42 return 1024LL * 1024LL * 1024LL * i
;
46 int ffn(const char *, const struct stat64
*, int, struct FTW
*);
48 #define BLOCKSIZE 4096
51 (sizeof(xfs_dir2_leaf_entry_t) + sizeof(xfs_dir2_data_entry_t))
54 #define FBLOCKS(n) ((n)/blocksize)
55 #define RFBYTES(n) ((n) - (FBLOCKS(n) * blocksize))
57 unsigned long long dirsize
=0; /* bytes */
58 unsigned long long logsize
=LOGSIZE
*BLOCKSIZE
; /* bytes */
59 unsigned long long fullblocks
=0; /* FS blocks */
60 unsigned long long isize
=0; /* inodes bytes */
61 unsigned long long blocksize
=BLOCKSIZE
;
62 unsigned long long nslinks
=0; /* number of symbolic links */
63 unsigned long long nfiles
=0; /* number of regular files */
64 unsigned long long ndirs
=0; /* number of directories */
65 unsigned long long nspecial
=0; /* number of special files */
66 unsigned long long verbose
=0; /* verbose mode TRUE/FALSE */
76 _("Usage: %s [opts] directory [directory ...]\n"
77 "\t-b blocksize (fundamental filesystem blocksize)\n"
78 "\t-i logsize (internal log size)\n"
79 "\t-e logsize (external log size)\n"
80 "\t-v prints more verbose messages\n"
81 "\t-V prints version and exits\n"
82 "\t-h prints this usage message\n\n"
83 "Note:\tblocksize may have 'k' appended to indicate x1024\n"
84 "\tlogsize may also have 'm' appended to indicate (1024 x 1024)\n"),
90 main(int argc
, char **argv
)
92 unsigned long long est
;
98 setlocale(LC_ALL
, "");
99 bindtextdomain(PACKAGE
, LOCALEDIR
);
102 while ((c
= getopt (argc
, argv
, "b:hdve:i:V")) != EOF
) {
105 blocksize
=cvtnum(optarg
);
106 if (blocksize
<= 0LL) {
107 fprintf(stderr
, _("blocksize %llu too small\n"),
111 else if (blocksize
> 64LL * 1024LL) {
112 fprintf(stderr
, _("blocksize %llu too large\n"),
119 fprintf(stderr
, _("already have external log "
120 "noted, can't have both\n"));
123 logsize
=cvtnum(optarg
);
128 fprintf(stderr
, _("already have internal log "
129 "noted, can't have both\n"));
132 logsize
=cvtnum(optarg
);
142 printf(_("%s version %s\n"), basename(argv
[0]), VERSION
);
153 if (!elog
&& !ilog
) {
155 logsize
=LOGSIZE
* blocksize
;
158 printf(_("directory bsize blocks megabytes logsize\n"));
160 for ( ; optind
< argc
; optind
++) {
161 dirsize
=0LL; /* bytes */
162 fullblocks
=0LL; /* FS blocks */
163 isize
=0LL; /* inodes bytes */
164 nslinks
=0LL; /* number of symbolic links */
165 nfiles
=0LL; /* number of regular files */
166 ndirs
=0LL; /* number of directories */
167 nspecial
=0LL; /* number of special files */
169 nftw64(argv
[optind
], ffn
, 40, FTW_PHYS
| FTW_MOUNT
);
172 printf(_("dirsize=%llu\n"), dirsize
);
173 printf(_("fullblocks=%llu\n"), fullblocks
);
174 printf(_("isize=%llu\n"), isize
);
176 printf(_("%llu regular files\n"), nfiles
);
177 printf(_("%llu symbolic links\n"), nslinks
);
178 printf(_("%llu directories\n"), ndirs
);
179 printf(_("%llu special files\n"), nspecial
);
182 est
= FBLOCKS(isize
) + 8 /* blocks for inodes */
183 + FBLOCKS(dirsize
) + 1 /* blocks for directories */
184 + fullblocks
/* blocks for file contents */
185 + (8 * 16) /* fudge for overhead blks (per ag) */
186 + FBLOCKS(isize
/ INODESIZE
); /* 1 byte/inode for map */
189 est
+= (logsize
/ blocksize
);
192 printf(_("%s will take about %.1f megabytes\n"),
194 (double)est
*(double)blocksize
/(1024.0*1024.0));
196 /* avoid running over 39 characters in field */
197 strncpy(dname
, argv
[optind
], 40);
199 printf(_("%-39s %5llu %8llu %10.1fMB %10llu\n"),
200 dname
, blocksize
, est
,
201 (double)est
*(double)blocksize
/(1024.0*1024.0), logsize
);
204 if (!verbose
&& elog
) {
205 printf(_("\twith the external log using %llu blocks "),
207 printf(_("or about %.1f megabytes\n"),
208 (double)logsize
/(1024.0*1024.0));
215 ffn(const char *path
, const struct stat64
*stb
, int flags
, struct FTW
*f
)
217 /* cases are in most-encountered to least-encountered order */
218 dirsize
+=PERDIRENTRY
+strlen(path
);
220 switch (S_IFMT
& stb
->st_mode
) {
221 case S_IFREG
: /* regular files */
222 fullblocks
+=FBLOCKS(stb
->st_blocks
* 512 + blocksize
-1);
223 if (stb
->st_blocks
* 512 < stb
->st_size
)
224 fullblocks
++; /* add one bmap block here */
227 case S_IFLNK
: /* symbolic links */
228 if (stb
->st_size
>= (INODESIZE
- (sizeof(xfs_dinode_t
)+4)))
229 fullblocks
+=FBLOCKS(stb
->st_size
+ blocksize
-1);
232 case S_IFDIR
: /* directories */
233 dirsize
+=blocksize
; /* fudge upwards */
234 if (stb
->st_size
>= blocksize
)
238 case S_IFIFO
: /* named pipes */
239 case S_IFCHR
: /* Character Special device */
240 case S_IFBLK
: /* Block Special device */
241 case S_IFSOCK
: /* socket */