]>
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"
14 #define TERABYTES(count, blog) ((uint64_t)(count) << (40 - (blog)))
15 #define GIGABYTES(count, blog) ((uint64_t)(count) << (30 - (blog)))
16 #define MEGABYTES(count, blog) ((uint64_t)(count) << (20 - (blog)))
19 calc_default_ag_geometry(
30 * First handle the high extreme - the point at which we will
31 * always use the maximum AG size.
33 * This applies regardless of storage configuration.
35 if (dblocks
>= TERABYTES(32, blocklog
)) {
36 blocks
= XFS_AG_MAX_BLOCKS(blocklog
);
41 * For a single underlying storage device over 4TB in size
42 * use the maximum AG size. Between 128MB and 4TB, just use
43 * 4 AGs and scale up smoothly between min/max AG sizes.
46 if (dblocks
>= TERABYTES(4, blocklog
)) {
47 blocks
= XFS_AG_MAX_BLOCKS(blocklog
);
49 } else if (dblocks
>= MEGABYTES(128, blocklog
)) {
50 shift
= XFS_NOMULTIDISK_AGLOG
;
56 * For the multidisk configs we choose an AG count based on the number
57 * of data blocks available, trying to keep the number of AGs higher
58 * than the single disk configurations. This makes the assumption that
59 * larger filesystems have more parallelism available to them.
61 shift
= XFS_MULTIDISK_AGLOG
;
62 if (dblocks
<= GIGABYTES(512, blocklog
))
64 if (dblocks
<= GIGABYTES(8, blocklog
))
66 if (dblocks
< MEGABYTES(128, blocklog
))
68 if (dblocks
< MEGABYTES(64, blocklog
))
70 if (dblocks
< MEGABYTES(32, blocklog
))
74 * If dblocks is not evenly divisible by the number of
75 * desired AGs, round "blocks" up so we don't lose the
76 * last bit of the filesystem. The same principle applies
77 * to the AG count, so we don't lose the last AG!
80 ASSERT(shift
>= 0 && shift
<= XFS_MULTIDISK_AGLOG
);
81 blocks
= dblocks
>> shift
;
82 if (dblocks
& xfs_mask32lo(shift
)) {
83 if (blocks
< XFS_AG_MAX_BLOCKS(blocklog
))
88 *agcount
= dblocks
/ blocks
+ (dblocks
% blocks
!= 0);
92 * Check for existing filesystem or partition table on device.
94 * 1 for existing fs or partition
96 * -1 for internal error
104 blkid_probe pr
= NULL
;
110 if (!device
|| !*device
)
113 ret
= -1; /* will reset on success of all setup calls */
115 fd
= open(device
, O_RDONLY
);
118 platform_findsizes((char *)device
, fd
, &size
, &bsz
);
121 /* nothing to overwrite on a 0-length device */
127 pr
= blkid_new_probe_from_filename(device
);
131 ret
= blkid_probe_enable_partitions(pr
, 1);
135 ret
= blkid_do_fullprobe(pr
);
140 * Blkid returns 1 for nothing found and 0 when it finds a signature,
141 * but we want the exact opposite, so reverse the return value here.
143 * In addition print some useful diagnostics about what actually is
151 if (!blkid_probe_lookup_value(pr
, "TYPE", &type
, NULL
)) {
153 _("%s: %s appears to contain an existing "
154 "filesystem (%s).\n"), progname
, device
, type
);
155 } else if (!blkid_probe_lookup_value(pr
, "PTTYPE", &type
, NULL
)) {
157 _("%s: %s appears to contain a partition "
158 "table (%s).\n"), progname
, device
, type
);
161 _("%s: %s appears to contain something weird "
162 "according to blkid\n"), progname
, device
);
167 blkid_free_probe(pr
);
170 _("%s: probe of %s failed, cannot detect "
171 "existing filesystem.\n"), progname
, device
);
175 static void blkid_get_topology(
189 /* can't get topology info from a file */
190 if (!stat(device
, &statbuf
) && S_ISREG(statbuf
.st_mode
)) {
192 _("%s: Warning: trying to probe topology of a file %s!\n"),
197 pr
= blkid_new_probe_from_filename(device
);
201 tp
= blkid_probe_get_topology(pr
);
205 val
= blkid_topology_get_logical_sector_size(tp
);
207 val
= blkid_topology_get_physical_sector_size(tp
);
209 val
= blkid_topology_get_minimum_io_size(tp
);
211 val
= blkid_topology_get_optimal_io_size(tp
);
215 * If the reported values are the same as the physical sector size
216 * do not bother to report anything. It will only cause warnings
217 * if people specify larger stripe units or widths manually.
219 if (*sunit
== *psectorsize
|| *swidth
== *psectorsize
) {
225 * Blkid reports the information in terms of bytes, but we want it in
226 * terms of 512 bytes blocks (only to convert it to bytes later..)
228 *sunit
= *sunit
>> 9;
229 *swidth
= *swidth
>> 9;
231 if (blkid_topology_get_alignment_offset(tp
) != 0) {
233 _("warning: device is not properly aligned %s\n"),
236 if (!force_overwrite
) {
238 _("Use -f to force usage of a misaligned device\n"));
242 /* Do not use physical sector size if the device is misaligned */
243 *psectorsize
= *lsectorsize
;
246 blkid_free_probe(pr
);
250 blkid_free_probe(pr
);
252 _("warning: unable to probe device topology for device %s\n"),
255 #else /* ifdef ENABLE_BLKID */
257 * Without blkid, we can't do a good check for signatures.
258 * So instead of some messy attempts, just disable any checks
259 * and always return 'nothing found'.
261 # warning BLKID is disabled, so signature detection and block device\
262 access are not working!
270 static void blkid_get_topology(
279 * Shouldn't make any difference (no blkid = no block device access),
280 * but make sure this dummy replacement returns with at least some
283 *lsectorsize
= *psectorsize
= 512;
286 #endif /* ENABLE_BLKID */
290 struct fs_topology
*ft
,
294 char *dfile
= xi
->volname
? xi
->volname
: xi
->dname
;
297 * If our target is a regular file, use platform_findsizes
298 * to try to obtain the underlying filesystem's requirements
299 * for direct IO; we'll set our sector size to that if possible.
302 (!stat(dfile
, &statbuf
) && S_ISREG(statbuf
.st_mode
))) {
304 int flags
= O_RDONLY
;
307 /* with xi->disfile we may not have the file yet! */
311 fd
= open(dfile
, flags
, 0666);
313 platform_findsizes(dfile
, fd
, &dummy
, &ft
->lsectorsize
);
315 ft
->psectorsize
= ft
->lsectorsize
;
317 ft
->psectorsize
= ft
->lsectorsize
= BBSIZE
;
319 blkid_get_topology(dfile
, &ft
->dsunit
, &ft
->dswidth
,
320 &ft
->lsectorsize
, &ft
->psectorsize
,
324 if (xi
->rtname
&& !xi
->risfile
) {
325 int sunit
, lsectorsize
, psectorsize
;
327 blkid_get_topology(xi
->rtname
, &sunit
, &ft
->rtswidth
,
328 &lsectorsize
, &psectorsize
, force_overwrite
);