]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libfrog/topology.c
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
10 # include <blkid/blkid.h>
11 #endif /* ENABLE_BLKID */
12 #include "xfs_multidisk.h"
16 #define TERABYTES(count, blog) ((uint64_t)(count) << (40 - (blog)))
17 #define GIGABYTES(count, blog) ((uint64_t)(count) << (30 - (blog)))
18 #define MEGABYTES(count, blog) ((uint64_t)(count) << (20 - (blog)))
21 calc_default_ag_geometry(
32 * First handle the high extreme - the point at which we will
33 * always use the maximum AG size.
35 * This applies regardless of storage configuration.
37 if (dblocks
>= TERABYTES(32, blocklog
)) {
38 blocks
= XFS_AG_MAX_BLOCKS(blocklog
);
43 * For a single underlying storage device over 4TB in size
44 * use the maximum AG size. Between 128MB and 4TB, just use
45 * 4 AGs and scale up smoothly between min/max AG sizes.
48 if (dblocks
>= TERABYTES(4, blocklog
)) {
49 blocks
= XFS_AG_MAX_BLOCKS(blocklog
);
51 } else if (dblocks
>= MEGABYTES(128, blocklog
)) {
52 shift
= XFS_NOMULTIDISK_AGLOG
;
58 * For the multidisk configs we choose an AG count based on the number
59 * of data blocks available, trying to keep the number of AGs higher
60 * than the single disk configurations. This makes the assumption that
61 * larger filesystems have more parallelism available to them.
63 shift
= XFS_MULTIDISK_AGLOG
;
64 if (dblocks
<= GIGABYTES(512, blocklog
))
66 if (dblocks
<= GIGABYTES(8, blocklog
))
68 if (dblocks
< MEGABYTES(128, blocklog
))
70 if (dblocks
< MEGABYTES(64, blocklog
))
72 if (dblocks
< MEGABYTES(32, blocklog
))
76 * If dblocks is not evenly divisible by the number of
77 * desired AGs, round "blocks" up so we don't lose the
78 * last bit of the filesystem. The same principle applies
79 * to the AG count, so we don't lose the last AG!
82 ASSERT(shift
>= 0 && shift
<= XFS_MULTIDISK_AGLOG
);
83 blocks
= dblocks
>> shift
;
84 if (dblocks
& xfs_mask32lo(shift
)) {
85 if (blocks
< XFS_AG_MAX_BLOCKS(blocklog
))
90 *agcount
= dblocks
/ blocks
+ (dblocks
% blocks
!= 0);
94 * Check for existing filesystem or partition table on device.
96 * 1 for existing fs or partition
98 * -1 for internal error
106 blkid_probe pr
= NULL
;
112 if (!device
|| !*device
)
115 ret
= -1; /* will reset on success of all setup calls */
117 fd
= open(device
, O_RDONLY
);
120 platform_findsizes((char *)device
, fd
, &size
, &bsz
);
123 /* nothing to overwrite on a 0-length device */
129 pr
= blkid_new_probe_from_filename(device
);
133 ret
= blkid_probe_enable_partitions(pr
, 1);
137 ret
= blkid_do_fullprobe(pr
);
142 * Blkid returns 1 for nothing found and 0 when it finds a signature,
143 * but we want the exact opposite, so reverse the return value here.
145 * In addition print some useful diagnostics about what actually is
153 if (!blkid_probe_lookup_value(pr
, "TYPE", &type
, NULL
)) {
155 _("%s: %s appears to contain an existing "
156 "filesystem (%s).\n"), progname
, device
, type
);
157 } else if (!blkid_probe_lookup_value(pr
, "PTTYPE", &type
, NULL
)) {
159 _("%s: %s appears to contain a partition "
160 "table (%s).\n"), progname
, device
, type
);
163 _("%s: %s appears to contain something weird "
164 "according to blkid\n"), progname
, device
);
169 blkid_free_probe(pr
);
172 _("%s: probe of %s failed, cannot detect "
173 "existing filesystem.\n"), progname
, device
);
177 static void blkid_get_topology(
191 /* can't get topology info from a file */
192 if (!stat(device
, &statbuf
) && S_ISREG(statbuf
.st_mode
)) {
194 _("%s: Warning: trying to probe topology of a file %s!\n"),
199 pr
= blkid_new_probe_from_filename(device
);
203 tp
= blkid_probe_get_topology(pr
);
207 val
= blkid_topology_get_logical_sector_size(tp
);
209 val
= blkid_topology_get_physical_sector_size(tp
);
211 val
= blkid_topology_get_minimum_io_size(tp
);
213 val
= blkid_topology_get_optimal_io_size(tp
);
217 * If the reported values are the same as the physical sector size
218 * do not bother to report anything. It will only cause warnings
219 * if people specify larger stripe units or widths manually.
221 if (*sunit
== *psectorsize
|| *swidth
== *psectorsize
) {
227 * Blkid reports the information in terms of bytes, but we want it in
228 * terms of 512 bytes blocks (only to convert it to bytes later..)
230 *sunit
= *sunit
>> 9;
231 *swidth
= *swidth
>> 9;
233 if (blkid_topology_get_alignment_offset(tp
) != 0) {
235 _("warning: device is not properly aligned %s\n"),
238 if (!force_overwrite
) {
240 _("Use -f to force usage of a misaligned device\n"));
244 /* Do not use physical sector size if the device is misaligned */
245 *psectorsize
= *lsectorsize
;
248 blkid_free_probe(pr
);
252 blkid_free_probe(pr
);
254 _("warning: unable to probe device topology for device %s\n"),
257 #else /* ifdef ENABLE_BLKID */
259 * Without blkid, we can't do a good check for signatures.
260 * So instead of some messy attempts, just disable any checks
261 * and always return 'nothing found'.
263 # warning BLKID is disabled, so signature detection and block device\
264 access are not working!
272 static void blkid_get_topology(
281 * Shouldn't make any difference (no blkid = no block device access),
282 * but make sure this dummy replacement returns with at least some
285 *lsectorsize
= *psectorsize
= 512;
288 #endif /* ENABLE_BLKID */
292 struct fs_topology
*ft
,
296 char *dfile
= xi
->volname
? xi
->volname
: xi
->dname
;
299 * If our target is a regular file, use platform_findsizes
300 * to try to obtain the underlying filesystem's requirements
301 * for direct IO; we'll set our sector size to that if possible.
304 (!stat(dfile
, &statbuf
) && S_ISREG(statbuf
.st_mode
))) {
306 int flags
= O_RDONLY
;
309 /* with xi->disfile we may not have the file yet! */
313 fd
= open(dfile
, flags
, 0666);
315 platform_findsizes(dfile
, fd
, &dummy
, &ft
->lsectorsize
);
317 ft
->psectorsize
= ft
->lsectorsize
;
319 ft
->psectorsize
= ft
->lsectorsize
= BBSIZE
;
321 blkid_get_topology(dfile
, &ft
->dsunit
, &ft
->dswidth
,
322 &ft
->lsectorsize
, &ft
->psectorsize
,
326 if (xi
->rtname
&& !xi
->risfile
) {
327 int sunit
, lsectorsize
, psectorsize
;
329 blkid_get_topology(xi
->rtname
, &sunit
, &ft
->rtswidth
,
330 &lsectorsize
, &psectorsize
, force_overwrite
);