]>
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"
15 #define TERABYTES(count, blog) ((uint64_t)(count) << (40 - (blog)))
16 #define GIGABYTES(count, blog) ((uint64_t)(count) << (30 - (blog)))
17 #define MEGABYTES(count, blog) ((uint64_t)(count) << (20 - (blog)))
20 calc_default_ag_geometry(
31 * First handle the high extreme - the point at which we will
32 * always use the maximum AG size.
34 * This applies regardless of storage configuration.
36 if (dblocks
>= TERABYTES(32, blocklog
)) {
37 blocks
= XFS_AG_MAX_BLOCKS(blocklog
);
42 * For a single underlying storage device over 4TB in size
43 * use the maximum AG size. Between 128MB and 4TB, just use
44 * 4 AGs and scale up smoothly between min/max AG sizes.
47 if (dblocks
>= TERABYTES(4, blocklog
)) {
48 blocks
= XFS_AG_MAX_BLOCKS(blocklog
);
50 } else if (dblocks
>= MEGABYTES(128, blocklog
)) {
51 shift
= XFS_NOMULTIDISK_AGLOG
;
57 * For the multidisk configs we choose an AG count based on the number
58 * of data blocks available, trying to keep the number of AGs higher
59 * than the single disk configurations. This makes the assumption that
60 * larger filesystems have more parallelism available to them.
62 shift
= XFS_MULTIDISK_AGLOG
;
63 if (dblocks
<= GIGABYTES(512, blocklog
))
65 if (dblocks
<= GIGABYTES(8, blocklog
))
67 if (dblocks
< MEGABYTES(128, blocklog
))
69 if (dblocks
< MEGABYTES(64, blocklog
))
71 if (dblocks
< MEGABYTES(32, blocklog
))
75 * If dblocks is not evenly divisible by the number of
76 * desired AGs, round "blocks" up so we don't lose the
77 * last bit of the filesystem. The same principle applies
78 * to the AG count, so we don't lose the last AG!
81 ASSERT(shift
>= 0 && shift
<= XFS_MULTIDISK_AGLOG
);
82 blocks
= dblocks
>> shift
;
83 if (dblocks
& xfs_mask32lo(shift
)) {
84 if (blocks
< XFS_AG_MAX_BLOCKS(blocklog
))
89 *agcount
= dblocks
/ blocks
+ (dblocks
% blocks
!= 0);
93 * Check for existing filesystem or partition table on device.
95 * 1 for existing fs or partition
97 * -1 for internal error
105 blkid_probe pr
= NULL
;
111 if (!device
|| !*device
)
114 ret
= -1; /* will reset on success of all setup calls */
116 fd
= open(device
, O_RDONLY
);
119 platform_findsizes((char *)device
, fd
, &size
, &bsz
);
122 /* nothing to overwrite on a 0-length device */
128 pr
= blkid_new_probe_from_filename(device
);
132 ret
= blkid_probe_enable_partitions(pr
, 1);
136 ret
= blkid_do_fullprobe(pr
);
141 * Blkid returns 1 for nothing found and 0 when it finds a signature,
142 * but we want the exact opposite, so reverse the return value here.
144 * In addition print some useful diagnostics about what actually is
152 if (!blkid_probe_lookup_value(pr
, "TYPE", &type
, NULL
)) {
154 _("%s: %s appears to contain an existing "
155 "filesystem (%s).\n"), progname
, device
, type
);
156 } else if (!blkid_probe_lookup_value(pr
, "PTTYPE", &type
, NULL
)) {
158 _("%s: %s appears to contain a partition "
159 "table (%s).\n"), progname
, device
, type
);
162 _("%s: %s appears to contain something weird "
163 "according to blkid\n"), progname
, device
);
168 blkid_free_probe(pr
);
171 _("%s: probe of %s failed, cannot detect "
172 "existing filesystem.\n"), progname
, device
);
176 static void blkid_get_topology(
190 /* can't get topology info from a file */
191 if (!stat(device
, &statbuf
) && S_ISREG(statbuf
.st_mode
)) {
193 _("%s: Warning: trying to probe topology of a file %s!\n"),
198 pr
= blkid_new_probe_from_filename(device
);
202 tp
= blkid_probe_get_topology(pr
);
206 val
= blkid_topology_get_logical_sector_size(tp
);
208 val
= blkid_topology_get_physical_sector_size(tp
);
210 val
= blkid_topology_get_minimum_io_size(tp
);
212 val
= blkid_topology_get_optimal_io_size(tp
);
216 * If the reported values are the same as the physical sector size
217 * do not bother to report anything. It will only cause warnings
218 * if people specify larger stripe units or widths manually.
220 if (*sunit
== *psectorsize
|| *swidth
== *psectorsize
) {
226 * Blkid reports the information in terms of bytes, but we want it in
227 * terms of 512 bytes blocks (only to convert it to bytes later..)
229 *sunit
= *sunit
>> 9;
230 *swidth
= *swidth
>> 9;
232 if (blkid_topology_get_alignment_offset(tp
) != 0) {
234 _("warning: device is not properly aligned %s\n"),
237 if (!force_overwrite
) {
239 _("Use -f to force usage of a misaligned device\n"));
243 /* Do not use physical sector size if the device is misaligned */
244 *psectorsize
= *lsectorsize
;
247 blkid_free_probe(pr
);
251 blkid_free_probe(pr
);
253 _("warning: unable to probe device topology for device %s\n"),
256 #else /* ifdef ENABLE_BLKID */
258 * Without blkid, we can't do a good check for signatures.
259 * So instead of some messy attempts, just disable any checks
260 * and always return 'nothing found'.
262 # warning BLKID is disabled, so signature detection and block device\
263 access are not working!
271 static void blkid_get_topology(
280 * Shouldn't make any difference (no blkid = no block device access),
281 * but make sure this dummy replacement returns with at least some
284 *lsectorsize
= *psectorsize
= 512;
287 #endif /* ENABLE_BLKID */
291 struct fs_topology
*ft
,
295 char *dfile
= xi
->volname
? xi
->volname
: xi
->dname
;
298 * If our target is a regular file, use platform_findsizes
299 * to try to obtain the underlying filesystem's requirements
300 * for direct IO; we'll set our sector size to that if possible.
303 (!stat(dfile
, &statbuf
) && S_ISREG(statbuf
.st_mode
))) {
305 int flags
= O_RDONLY
;
308 /* with xi->disfile we may not have the file yet! */
312 fd
= open(dfile
, flags
, 0666);
314 platform_findsizes(dfile
, fd
, &dummy
, &ft
->lsectorsize
);
316 ft
->psectorsize
= ft
->lsectorsize
;
318 ft
->psectorsize
= ft
->lsectorsize
= BBSIZE
;
320 blkid_get_topology(dfile
, &ft
->dsunit
, &ft
->dswidth
,
321 &ft
->lsectorsize
, &ft
->psectorsize
,
325 if (xi
->rtname
&& !xi
->risfile
) {
326 int sunit
, lsectorsize
, psectorsize
;
328 blkid_get_topology(xi
->rtname
, &sunit
, &ft
->rtswidth
,
329 &lsectorsize
, &psectorsize
, force_overwrite
);