]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - estimate/xfs_estimate.c
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2002 Silicon Graphics, Inc.
8 * Estimate space of an XFS filesystem
10 * XXX: assumes dirv1 format.
16 static unsigned long long
22 i
= strtoll(s
, &sp
, 0);
23 if (i
== 0 && sp
== s
)
27 if (*sp
=='k' && sp
[1] == '\0')
29 if (*sp
=='m' && sp
[1] == '\0')
30 return 1024LL * 1024LL * i
;
31 if (*sp
=='g' && sp
[1] == '\0')
32 return 1024LL * 1024LL * 1024LL * i
;
36 int ffn(const char *, const struct stat
*, int, struct FTW
*);
38 #define BLOCKSIZE 4096
41 (sizeof(xfs_dir2_leaf_entry_t) + sizeof(xfs_dir2_data_entry_t))
44 #define FBLOCKS(n) ((n)/blocksize)
46 static unsigned long long dirsize
=0; /* bytes */
47 static unsigned long long logsize
=LOGSIZE
*BLOCKSIZE
; /* bytes */
48 static unsigned long long fullblocks
=0; /* FS blocks */
49 static unsigned long long isize
=0; /* inodes bytes */
50 static unsigned long long blocksize
=BLOCKSIZE
;
51 static unsigned long long nslinks
=0; /* number of symbolic links */
52 static unsigned long long nfiles
=0; /* number of regular files */
53 static unsigned long long ndirs
=0; /* number of directories */
54 static unsigned long long nspecial
=0; /* number of special files */
55 static unsigned long long verbose
=0; /* verbose mode TRUE/FALSE */
57 static int __debug
= 0;
65 _("Usage: %s [opts] directory [directory ...]\n"
66 "\t-b blocksize (fundamental filesystem blocksize)\n"
67 "\t-i logsize (internal log size)\n"
68 "\t-e logsize (external log size)\n"
69 "\t-v prints more verbose messages\n"
70 "\t-V prints version and exits\n"
71 "\t-h prints this usage message\n\n"
72 "Note:\tblocksize may have 'k' appended to indicate x1024\n"
73 "\tlogsize may also have 'm' appended to indicate (1024 x 1024)\n"),
79 main(int argc
, char **argv
)
81 unsigned long long est
;
87 setlocale(LC_ALL
, "");
88 bindtextdomain(PACKAGE
, LOCALEDIR
);
91 while ((c
= getopt (argc
, argv
, "b:hdve:i:V")) != EOF
) {
94 blocksize
=cvtnum(optarg
);
95 if (blocksize
<= 0LL) {
96 fprintf(stderr
, _("blocksize %llu too small\n"),
100 else if (blocksize
> 64LL * 1024LL) {
101 fprintf(stderr
, _("blocksize %llu too large\n"),
108 fprintf(stderr
, _("already have external log "
109 "noted, can't have both\n"));
112 logsize
=cvtnum(optarg
);
117 fprintf(stderr
, _("already have internal log "
118 "noted, can't have both\n"));
121 logsize
=cvtnum(optarg
);
131 printf(_("%s version %s\n"), basename(argv
[0]), VERSION
);
142 if (!elog
&& !ilog
) {
144 logsize
=LOGSIZE
* blocksize
;
147 printf(_("directory bsize blocks megabytes logsize\n"));
149 for ( ; optind
< argc
; optind
++) {
150 dirsize
=0LL; /* bytes */
151 fullblocks
=0LL; /* FS blocks */
152 isize
=0LL; /* inodes bytes */
153 nslinks
=0LL; /* number of symbolic links */
154 nfiles
=0LL; /* number of regular files */
155 ndirs
=0LL; /* number of directories */
156 nspecial
=0LL; /* number of special files */
158 nftw(argv
[optind
], ffn
, 40, FTW_PHYS
| FTW_MOUNT
);
161 printf(_("dirsize=%llu\n"), dirsize
);
162 printf(_("fullblocks=%llu\n"), fullblocks
);
163 printf(_("isize=%llu\n"), isize
);
165 printf(_("%llu regular files\n"), nfiles
);
166 printf(_("%llu symbolic links\n"), nslinks
);
167 printf(_("%llu directories\n"), ndirs
);
168 printf(_("%llu special files\n"), nspecial
);
171 est
= FBLOCKS(isize
) + 8 /* blocks for inodes */
172 + FBLOCKS(dirsize
) + 1 /* blocks for directories */
173 + fullblocks
/* blocks for file contents */
174 + (8 * 16) /* fudge for overhead blks (per ag) */
175 + FBLOCKS(isize
/ INODESIZE
); /* 1 byte/inode for map */
178 est
+= (logsize
/ blocksize
);
181 printf(_("%s will take about %.1f megabytes\n"),
183 (double)est
*(double)blocksize
/(1024.0*1024.0));
185 /* avoid running over 39 characters in field */
186 strncpy(dname
, argv
[optind
], 40);
188 printf(_("%-39s %5llu %8llu %10.1fMB %10llu\n"),
189 dname
, blocksize
, est
,
190 (double)est
*(double)blocksize
/(1024.0*1024.0), logsize
);
193 if (!verbose
&& elog
) {
194 printf(_("\twith the external log using %llu blocks "),
196 printf(_("or about %.1f megabytes\n"),
197 (double)logsize
/(1024.0*1024.0));
204 ffn(const char *path
, const struct stat
*stb
, int flags
, struct FTW
*f
)
206 /* cases are in most-encountered to least-encountered order */
207 dirsize
+=PERDIRENTRY
+strlen(path
);
209 switch (S_IFMT
& stb
->st_mode
) {
210 case S_IFREG
: /* regular files */
211 fullblocks
+=FBLOCKS(stb
->st_blocks
* 512 + blocksize
-1);
212 if (stb
->st_blocks
* 512 < stb
->st_size
)
213 fullblocks
++; /* add one bmap block here */
216 case S_IFLNK
: /* symbolic links */
217 if (stb
->st_size
>= (INODESIZE
- (sizeof(xfs_dinode_t
)+4)))
218 fullblocks
+=FBLOCKS(stb
->st_size
+ blocksize
-1);
221 case S_IFDIR
: /* directories */
222 dirsize
+=blocksize
; /* fudge upwards */
223 if (stb
->st_size
>= blocksize
)
227 case S_IFIFO
: /* named pipes */
228 case S_IFCHR
: /* Character Special device */
229 case S_IFBLK
: /* Block Special device */
230 case S_IFSOCK
: /* socket */