]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - libxfs/init.c
libxfs: replace xfs_sb_version checks with feature flag checks
[thirdparty/xfsprogs-dev.git] / libxfs / init.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0
2bd0ea18 2/*
da23017d
NS
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
2bd0ea18
NS
5 */
6
2bd0ea18 7#include <sys/stat.h>
9440d84d 8#include "init.h"
29e62271 9
9c799827 10#include "libxfs_priv.h"
b626fb59
DC
11#include "xfs_fs.h"
12#include "xfs_shared.h"
13#include "xfs_format.h"
14#include "xfs_log_format.h"
15#include "xfs_trans_resv.h"
16#include "xfs_mount.h"
794a5604 17#include "xfs_defer.h"
b626fb59
DC
18#include "xfs_inode_buf.h"
19#include "xfs_inode_fork.h"
20#include "xfs_inode.h"
21#include "xfs_trans.h"
b3a96b46 22#include "xfs_rmap_btree.h"
e7be6330 23#include "xfs_refcount_btree.h"
b658de93 24#include "libfrog/platform.h"
b626fb59 25
6b803e5a 26#include "libxfs.h" /* for now */
b626fb59 27
7448af58
DW
28#ifndef HAVE_LIBURCU_ATOMIC64
29pthread_mutex_t atomic64_lock = PTHREAD_MUTEX_INITIALIZER;
30#endif
31
2bd0ea18
NS
32char *progname = "libxfs"; /* default, changed by each tool */
33
f1b058f9 34struct cache *libxfs_bcache; /* global buffer cache */
9f38f08d 35int libxfs_bhash_size; /* #buckets in bcache */
f1b058f9 36
167137fe 37int use_xfs_buf_lock; /* global flag: use xfs_buf locks for MT */
d0572de5 38
2bd0ea18
NS
39/*
40 * dev_map - map open devices to fd.
41 */
42#define MAX_DEVS 10 /* arbitary maximum */
00ff2b10 43static int nextfakedev = -1; /* device number to give to next fake device */
2bd0ea18 44static struct dev_to_fd {
9440d84d
NS
45 dev_t dev;
46 int fd;
2bd0ea18
NS
47} dev_map[MAX_DEVS]={{0}};
48
2bd0ea18
NS
49/*
50 * Checks whether a given device has a mounted, writable
51 * filesystem, returns 1 if it does & fatal (just warns
52 * if not fatal, but allows us to proceed).
5000d01d 53 *
2bd0ea18
NS
54 * Useful to tools which will produce uncertain results
55 * if the filesystem is active - repair, check, logprint.
56 */
57static int
58check_isactive(char *name, char *block, int fatal)
59{
f594a0d1 60 struct stat st;
2bd0ea18 61
f594a0d1 62 if (stat(block, &st) < 0)
9440d84d 63 return 0;
fc8202ba 64 if ((st.st_mode & S_IFMT) != S_IFBLK)
9440d84d 65 return 0;
93d9f139 66 if (platform_check_ismounted(name, block, &st, 0) == 0)
9440d84d 67 return 0;
7f510afb
ES
68 if (platform_check_iswritable(name, block, &st))
69 return fatal ? 1 : 0;
70 return 0;
2bd0ea18
NS
71}
72
5000d01d 73/* libxfs_device_to_fd:
2bd0ea18
NS
74 * lookup a device number in the device map
75 * return the associated fd
76 */
77int
78libxfs_device_to_fd(dev_t device)
79{
9440d84d 80 int d;
5000d01d 81
9440d84d 82 for (d = 0; d < MAX_DEVS; d++)
5000d01d 83 if (dev_map[d].dev == device)
2bd0ea18 84 return dev_map[d].fd;
5000d01d 85
9440d84d
NS
86 fprintf(stderr, _("%s: %s: device %lld is not open\n"),
87 progname, __FUNCTION__, (long long)device);
2bd0ea18 88 exit(1);
25d246df 89 /* NOTREACHED */
2bd0ea18
NS
90}
91
92/* libxfs_device_open:
93 * open a device and return its device number
94 */
95dev_t
7eb6693f 96libxfs_device_open(char *path, int creat, int xflags, int setblksize)
2bd0ea18 97{
2bd0ea18 98 dev_t dev;
7eb6693f 99 int fd, d, flags;
b74a1f6a 100 int readonly, dio, excl;
f594a0d1 101 struct stat statb;
7eb6693f
NS
102
103 readonly = (xflags & LIBXFS_ISREADONLY);
104 excl = (xflags & LIBXFS_EXCLUSIVELY) && !creat;
b74a1f6a 105 dio = (xflags & LIBXFS_DIRECT) && !creat && platform_direct_blockdev();
2bd0ea18 106
b74a1f6a 107retry:
7eb6693f
NS
108 flags = (readonly ? O_RDONLY : O_RDWR) | \
109 (creat ? (O_CREAT|O_TRUNC) : 0) | \
b74a1f6a 110 (dio ? O_DIRECT : 0) | \
7eb6693f 111 (excl ? O_EXCL : 0);
b74a1f6a 112
7eb6693f 113 if ((fd = open(path, flags, 0666)) < 0) {
b74a1f6a
NS
114 if (errno == EINVAL && --dio == 0)
115 goto retry;
9440d84d 116 fprintf(stderr, _("%s: cannot open %s: %s\n"),
2bd0ea18
NS
117 progname, path, strerror(errno));
118 exit(1);
119 }
120
f594a0d1 121 if (fstat(fd, &statb) < 0) {
9440d84d 122 fprintf(stderr, _("%s: cannot stat %s: %s\n"),
2bd0ea18
NS
123 progname, path, strerror(errno));
124 exit(1);
125 }
a33a9e62 126
edd45774
TS
127 if (!readonly && setblksize && (statb.st_mode & S_IFMT) == S_IFBLK) {
128 if (setblksize == 1)
129 /* use the default blocksize */
130 (void)platform_set_blocksize(fd, path, statb.st_rdev, XFS_MIN_SECTORSIZE, 0);
131 else {
132 /* given an explicit blocksize to use */
133 if (platform_set_blocksize(fd, path, statb.st_rdev, setblksize, 1))
134 exit(1);
135 }
136 }
2bd0ea18 137
a33a9e62
NS
138 /*
139 * Get the device number from the stat buf - unless
2bd0ea18 140 * we're not opening a real device, in which case
a33a9e62 141 * choose a new fake device number.
2bd0ea18 142 */
32181a02 143 dev = (statb.st_rdev) ? (statb.st_rdev) : (nextfakedev--);
2bd0ea18 144
32181a02 145 for (d = 0; d < MAX_DEVS; d++)
2bd0ea18 146 if (dev_map[d].dev == dev) {
9440d84d 147 fprintf(stderr, _("%s: device %lld is already open\n"),
5b64e00a 148 progname, (long long)dev);
2bd0ea18
NS
149 exit(1);
150 }
151
32181a02 152 for (d = 0; d < MAX_DEVS; d++)
2bd0ea18 153 if (!dev_map[d].dev) {
32181a02
NS
154 dev_map[d].dev = dev;
155 dev_map[d].fd = fd;
5000d01d 156
2bd0ea18
NS
157 return dev;
158 }
159
9440d84d
NS
160 fprintf(stderr, _("%s: %s: too many open devices\n"),
161 progname, __FUNCTION__);
2bd0ea18 162 exit(1);
25d246df 163 /* NOTREACHED */
2bd0ea18
NS
164}
165
166void
167libxfs_device_close(dev_t dev)
168{
5000d01d 169 int d;
2bd0ea18 170
32181a02 171 for (d = 0; d < MAX_DEVS; d++)
2bd0ea18 172 if (dev_map[d].dev == dev) {
023ba280 173 int fd, ret;
5000d01d 174
32181a02
NS
175 fd = dev_map[d].fd;
176 dev_map[d].dev = dev_map[d].fd = 0;
5000d01d 177
023ba280
DW
178 ret = platform_flush_device(fd, dev);
179 if (ret) {
180 ret = -errno;
181 fprintf(stderr,
182 _("%s: flush of device %lld failed, err=%d"),
183 progname, (long long)dev, ret);
184 }
2bd0ea18 185 close(fd);
5000d01d 186
2bd0ea18
NS
187 return;
188 }
189
9440d84d
NS
190 fprintf(stderr, _("%s: %s: device %lld is not open\n"),
191 progname, __FUNCTION__, (long long)dev);
2bd0ea18
NS
192 exit(1);
193}
194
74668075
NS
195static int
196check_open(char *path, int flags, char **rawfile, char **blockfile)
197{
c781939c
RC
198 int readonly = (flags & LIBXFS_ISREADONLY);
199 int inactive = (flags & LIBXFS_ISINACTIVE);
200 int dangerously = (flags & LIBXFS_DANGEROUSLY);
f594a0d1 201 struct stat stbuf;
c781939c 202
f594a0d1 203 if (stat(path, &stbuf) < 0) {
c781939c
RC
204 perror(path);
205 return 0;
206 }
b74a1f6a 207 if (!(*rawfile = platform_findrawpath(path))) {
c781939c
RC
208 fprintf(stderr, _("%s: "
209 "can't find a character device matching %s\n"),
210 progname, path);
211 return 0;
212 }
b74a1f6a 213 if (!(*blockfile = platform_findblockpath(path))) {
c781939c
RC
214 fprintf(stderr, _("%s: "
215 "can't find a block device matching %s\n"),
216 progname, path);
217 return 0;
218 }
219 if (!readonly && !inactive && platform_check_ismounted(path, *blockfile, NULL, 1))
220 return 0;
e08f5594 221
c781939c
RC
222 if (inactive && check_isactive(path, *blockfile, ((readonly|dangerously)?1:0)))
223 return 0;
224
225 return 1;
226}
227
7a326ce0
ES
228/*
229 * Initialize/destroy all of the zone allocators we use.
230 */
231static void
232init_zones(void)
233{
234 /* initialise zone allocation */
235 xfs_buf_zone = kmem_zone_init(sizeof(struct xfs_buf), "xfs_buffer");
236 xfs_inode_zone = kmem_zone_init(sizeof(struct xfs_inode), "xfs_inode");
237 xfs_ifork_zone = kmem_zone_init(sizeof(struct xfs_ifork), "xfs_ifork");
238 xfs_ili_zone = kmem_zone_init(
239 sizeof(struct xfs_inode_log_item),"xfs_inode_log_item");
240 xfs_buf_item_zone = kmem_zone_init(
241 sizeof(struct xfs_buf_log_item), "xfs_buf_log_item");
242 xfs_da_state_zone = kmem_zone_init(
243 sizeof(struct xfs_da_state), "xfs_da_state");
244 xfs_btree_cur_zone = kmem_zone_init(
245 sizeof(struct xfs_btree_cur), "xfs_btree_cur");
246 xfs_bmap_free_item_zone = kmem_zone_init(
247 sizeof(struct xfs_extent_free_item),
248 "xfs_bmap_free_item");
249 xfs_trans_zone = kmem_zone_init(
250 sizeof(struct xfs_trans), "xfs_trans");
251}
252
253static int
254destroy_zones(void)
255{
256 int leaked = 0;
257
258 leaked += kmem_zone_destroy(xfs_buf_zone);
259 leaked += kmem_zone_destroy(xfs_ili_zone);
260 leaked += kmem_zone_destroy(xfs_inode_zone);
261 leaked += kmem_zone_destroy(xfs_ifork_zone);
262 leaked += kmem_zone_destroy(xfs_buf_item_zone);
263 leaked += kmem_zone_destroy(xfs_da_state_zone);
264 leaked += kmem_zone_destroy(xfs_btree_cur_zone);
265 leaked += kmem_zone_destroy(xfs_bmap_free_item_zone);
266 leaked += kmem_zone_destroy(xfs_trans_zone);
267
268 return leaked;
269}
270
a9468486
DW
271static void
272libxfs_close_devices(
273 struct libxfs_xinit *li)
274{
275 if (li->ddev)
276 libxfs_device_close(li->ddev);
277 if (li->logdev && li->logdev != li->ddev)
278 libxfs_device_close(li->logdev);
279 if (li->rtdev)
280 libxfs_device_close(li->rtdev);
281
282 li->ddev = li->logdev = li->rtdev = 0;
283 li->dfd = li->logfd = li->rtfd = -1;
284}
285
2bd0ea18
NS
286/*
287 * libxfs initialization.
288 * Caller gets a 0 on failure (and we print a message), 1 on success.
289 */
290int
291libxfs_init(libxfs_init_t *a)
292{
293 char *blockfile;
2bd0ea18
NS
294 char *dname;
295 char dpath[25];
296 int fd;
297 char *logname;
298 char logpath[25];
2bd0ea18
NS
299 char *rawfile;
300 char *rtname;
301 char rtpath[25];
302 int rval = 0;
c781939c 303 int flags;
2bd0ea18
NS
304
305 dpath[0] = logpath[0] = rtpath[0] = '\0';
306 dname = a->dname;
307 logname = a->logname;
308 rtname = a->rtname;
2bd0ea18 309 a->dfd = a->logfd = a->rtfd = -1;
74668075 310 a->ddev = a->logdev = a->rtdev = 0;
06ac92fd
DC
311 a->dsize = a->lbsize = a->rtbsize = 0;
312 a->dbsize = a->logBBsize = a->logBBstart = a->rtsize = 0;
2bd0ea18 313
2bd0ea18 314 fd = -1;
b74a1f6a 315 flags = (a->isreadonly | a->isdirect);
c781939c 316
e4da1b16
DC
317 rcu_init();
318 rcu_register_thread();
bacd44a5
AE
319 radix_tree_init();
320
2bd0ea18 321 if (a->volname) {
c781939c 322 if(!check_open(a->volname,flags,&rawfile,&blockfile))
2bd0ea18 323 goto done;
2bd0ea18 324 fd = open(rawfile, O_RDONLY);
eb37fca5
NS
325 dname = a->dname = a->volname;
326 a->volname = NULL;
2bd0ea18 327 }
2bd0ea18 328 if (dname) {
2bd0ea18 329 if (a->disfile) {
7eb6693f 330 a->ddev= libxfs_device_open(dname, a->dcreat, flags,
c5907b96 331 a->setblksize);
2bd0ea18 332 a->dfd = libxfs_device_to_fd(a->ddev);
06ac92fd
DC
333 platform_findsizes(dname, a->dfd, &a->dsize,
334 &a->dbsize);
2bd0ea18 335 } else {
f02037ce 336 if (!check_open(dname, flags, &rawfile, &blockfile))
2bd0ea18
NS
337 goto done;
338 a->ddev = libxfs_device_open(rawfile,
7eb6693f 339 a->dcreat, flags, a->setblksize);
2bd0ea18 340 a->dfd = libxfs_device_to_fd(a->ddev);
f02037ce 341 platform_findsizes(rawfile, a->dfd,
06ac92fd 342 &a->dsize, &a->dbsize);
2bd0ea18 343 }
2bd0ea18
NS
344 } else
345 a->dsize = 0;
346 if (logname) {
2bd0ea18
NS
347 if (a->lisfile) {
348 a->logdev = libxfs_device_open(logname,
7eb6693f 349 a->lcreat, flags, a->setblksize);
2bd0ea18 350 a->logfd = libxfs_device_to_fd(a->logdev);
06ac92fd
DC
351 platform_findsizes(dname, a->logfd, &a->logBBsize,
352 &a->lbsize);
2bd0ea18 353 } else {
f02037ce 354 if (!check_open(logname, flags, &rawfile, &blockfile))
2bd0ea18
NS
355 goto done;
356 a->logdev = libxfs_device_open(rawfile,
7eb6693f 357 a->lcreat, flags, a->setblksize);
2bd0ea18 358 a->logfd = libxfs_device_to_fd(a->logdev);
f02037ce 359 platform_findsizes(rawfile, a->logfd,
06ac92fd 360 &a->logBBsize, &a->lbsize);
2bd0ea18 361 }
2bd0ea18
NS
362 } else
363 a->logBBsize = 0;
364 if (rtname) {
2bd0ea18
NS
365 if (a->risfile) {
366 a->rtdev = libxfs_device_open(rtname,
7eb6693f 367 a->rcreat, flags, a->setblksize);
2bd0ea18 368 a->rtfd = libxfs_device_to_fd(a->rtdev);
06ac92fd
DC
369 platform_findsizes(dname, a->rtfd, &a->rtsize,
370 &a->rtbsize);
2bd0ea18 371 } else {
f02037ce 372 if (!check_open(rtname, flags, &rawfile, &blockfile))
2bd0ea18
NS
373 goto done;
374 a->rtdev = libxfs_device_open(rawfile,
7eb6693f 375 a->rcreat, flags, a->setblksize);
2bd0ea18 376 a->rtfd = libxfs_device_to_fd(a->rtdev);
f02037ce 377 platform_findsizes(rawfile, a->rtfd,
06ac92fd 378 &a->rtsize, &a->rtbsize);
2bd0ea18 379 }
2bd0ea18
NS
380 } else
381 a->rtsize = 0;
382 if (a->dsize < 0) {
9440d84d 383 fprintf(stderr, _("%s: can't get size for data subvolume\n"),
2bd0ea18
NS
384 progname);
385 goto done;
386 }
387 if (a->logBBsize < 0) {
9440d84d 388 fprintf(stderr, _("%s: can't get size for log subvolume\n"),
2bd0ea18
NS
389 progname);
390 goto done;
391 }
392 if (a->rtsize < 0) {
9440d84d 393 fprintf(stderr, _("%s: can't get size for realtime subvolume\n"),
2bd0ea18
NS
394 progname);
395 goto done;
396 }
9f38f08d
MV
397 if (!libxfs_bhash_size)
398 libxfs_bhash_size = LIBXFS_BHASHSIZE(sbp);
ba9ecd40
DC
399 libxfs_bcache = cache_init(a->bcache_flags, libxfs_bhash_size,
400 &libxfs_bcache_operations);
d0572de5 401 use_xfs_buf_lock = a->usebuflock;
7a326ce0
ES
402 xfs_dir_startup();
403 init_zones();
2bd0ea18
NS
404 rval = 1;
405done:
406 if (dpath[0])
407 unlink(dpath);
408 if (logpath[0])
409 unlink(logpath);
410 if (rtpath[0])
411 unlink(rtpath);
412 if (fd >= 0)
413 close(fd);
c1ab394a 414 if (!rval) {
a9468486 415 libxfs_close_devices(a);
c1ab394a
DW
416 rcu_unregister_thread();
417 }
a9468486 418
2bd0ea18
NS
419 return rval;
420}
421
422
b391b7cd
NS
423/*
424 * Initialize realtime fields in the mount structure.
425 */
426static int
427rtmount_init(
39798eb5
NS
428 xfs_mount_t *mp, /* file system mount structure */
429 int flags)
b391b7cd 430{
31079e67 431 struct xfs_buf *bp; /* buffer for last block of subvolume */
b391b7cd 432 xfs_daddr_t d; /* address of last block of subvolume */
31079e67 433 int error;
b391b7cd 434
575f24e5 435 if (mp->m_sb.sb_rblocks == 0)
b391b7cd 436 return 0;
4aaeedc4 437
eefdf2ab 438 if (xfs_has_reflink(mp)) {
4aaeedc4
DW
439 fprintf(stderr,
440 _("%s: Reflink not compatible with realtime device. Please try a newer xfsprogs.\n"),
441 progname);
442 return -1;
443 }
444
eefdf2ab 445 if (xfs_has_rmapbt(mp)) {
4aaeedc4
DW
446 fprintf(stderr,
447 _("%s: Reverse mapping btree not compatible with realtime device. Please try a newer xfsprogs.\n"),
448 progname);
449 return -1;
450 }
451
ab434d12 452 if (mp->m_rtdev_targp->bt_bdev == 0 && !(flags & LIBXFS_MOUNT_DEBUGGER)) {
9440d84d 453 fprintf(stderr, _("%s: filesystem has a realtime subvolume\n"),
b391b7cd
NS
454 progname);
455 return -1;
456 }
575f24e5 457 mp->m_rsumlevels = mp->m_sb.sb_rextslog + 1;
b391b7cd
NS
458 mp->m_rsumsize =
459 (uint)sizeof(xfs_suminfo_t) * mp->m_rsumlevels *
575f24e5
DW
460 mp->m_sb.sb_rbmblocks;
461 mp->m_rsumsize = roundup(mp->m_rsumsize, mp->m_sb.sb_blocksize);
b391b7cd 462 mp->m_rbmip = mp->m_rsumip = NULL;
39798eb5
NS
463
464 /*
465 * Allow debugger to be run without the realtime device present.
466 */
467 if (flags & LIBXFS_MOUNT_DEBUGGER)
468 return 0;
469
b391b7cd
NS
470 /*
471 * Check that the realtime section is an ok size.
472 */
473 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks);
474 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_rblocks) {
9440d84d
NS
475 fprintf(stderr, _("%s: realtime init - %llu != %llu\n"),
476 progname, (unsigned long long) XFS_BB_TO_FSB(mp, d),
b391b7cd
NS
477 (unsigned long long) mp->m_sb.sb_rblocks);
478 return -1;
479 }
31079e67
DW
480 error = libxfs_buf_read(mp->m_rtdev, d - XFS_FSB_TO_BB(mp, 1),
481 XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL);
482 if (error) {
9440d84d
NS
483 fprintf(stderr, _("%s: realtime size check failed\n"),
484 progname);
b391b7cd
NS
485 return -1;
486 }
e02ba985 487 libxfs_buf_relse(bp);
b391b7cd
NS
488 return 0;
489}
490
b9ee1227
DW
491/*
492 * Set parameters for inode allocation heuristics, taking into account
493 * filesystem size and inode32/inode64 mount options; i.e. specifically
494 * whether or not XFS_MOUNT_SMALL_INUMS is set.
495 *
496 * Inode allocation patterns are altered only if inode32 is requested
497 * (XFS_MOUNT_SMALL_INUMS), and the filesystem is sufficiently large.
498 * If altered, XFS_MOUNT_32BITINODES is set as well.
499 *
500 * An agcount independent of that in the mount structure is provided
501 * because in the growfs case, mp->m_sb.sb_agcount is not yet updated
502 * to the potentially higher ag count.
503 *
504 * Returns the maximum AG index which may contain inodes.
505 */
506xfs_agnumber_t
507xfs_set_inode_alloc(
508 struct xfs_mount *mp,
509 xfs_agnumber_t agcount)
510{
511 xfs_agnumber_t index;
512 xfs_agnumber_t maxagi = 0;
513 xfs_sb_t *sbp = &mp->m_sb;
514 xfs_agnumber_t max_metadata;
515 xfs_agino_t agino;
516 xfs_ino_t ino;
517
518 /*
519 * Calculate how much should be reserved for inodes to meet
520 * the max inode percentage. Used only for inode32.
521 */
522 if (M_IGEO(mp)->maxicount) {
523 uint64_t icount;
524
525 icount = sbp->sb_dblocks * sbp->sb_imax_pct;
526 do_div(icount, 100);
527 icount += sbp->sb_agblocks - 1;
528 do_div(icount, sbp->sb_agblocks);
529 max_metadata = icount;
530 } else {
531 max_metadata = agcount;
532 }
533
534 /* Get the last possible inode in the filesystem */
535 agino = XFS_AGB_TO_AGINO(mp, sbp->sb_agblocks - 1);
536 ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
537
538 /*
539 * If user asked for no more than 32-bit inodes, and the fs is
540 * sufficiently large, set XFS_MOUNT_32BITINODES if we must alter
541 * the allocator to accommodate the request.
542 */
0ee9753e
DC
543 if (xfs_has_small_inums(mp) && ino > XFS_MAXINUMBER_32) {
544 xfs_set_inode32(mp);
b9ee1227 545 mp->m_flags |= XFS_MOUNT_32BITINODES;
0ee9753e
DC
546 } else {
547 xfs_clear_inode32(mp);
b9ee1227 548 mp->m_flags &= ~XFS_MOUNT_32BITINODES;
0ee9753e 549 }
b9ee1227
DW
550
551 for (index = 0; index < agcount; index++) {
552 struct xfs_perag *pag;
553
554 ino = XFS_AGINO_TO_INO(mp, index, agino);
555
556 pag = xfs_perag_get(mp, index);
557
0ee9753e 558 if (xfs_is_inode32(mp)) {
b9ee1227
DW
559 if (ino > XFS_MAXINUMBER_32) {
560 pag->pagi_inodeok = 0;
561 pag->pagf_metadata = 0;
562 } else {
563 pag->pagi_inodeok = 1;
564 maxagi++;
565 if (index < max_metadata)
566 pag->pagf_metadata = 1;
567 else
568 pag->pagf_metadata = 0;
569 }
570 } else {
571 pag->pagi_inodeok = 1;
572 pag->pagf_metadata = 0;
573 }
574
575 xfs_perag_put(pag);
576 }
577
0ee9753e 578 return xfs_is_inode32(mp) ? maxagi : agcount;
b9ee1227
DW
579}
580
75c8b434
DC
581static struct xfs_buftarg *
582libxfs_buftarg_alloc(
583 struct xfs_mount *mp,
704e4cef
DW
584 dev_t dev,
585 unsigned long write_fails)
75c8b434
DC
586{
587 struct xfs_buftarg *btp;
588
589 btp = malloc(sizeof(*btp));
590 if (!btp) {
591 fprintf(stderr, _("%s: buftarg init failed\n"),
592 progname);
593 exit(1);
594 }
595 btp->bt_mount = mp;
ab434d12 596 btp->bt_bdev = dev;
c335b673 597 btp->flags = 0;
704e4cef
DW
598 if (write_fails) {
599 btp->writes_left = write_fails;
600 btp->flags |= XFS_BUFTARG_INJECT_WRITE_FAIL;
601 }
602 pthread_mutex_init(&btp->lock, NULL);
c335b673 603
75c8b434
DC
604 return btp;
605}
606
704e4cef
DW
607enum libxfs_write_failure_nums {
608 WF_DATA = 0,
609 WF_LOG,
610 WF_RT,
611 WF_MAX_OPTS,
612};
613
614static char *wf_opts[] = {
615 [WF_DATA] = "ddev",
616 [WF_LOG] = "logdev",
617 [WF_RT] = "rtdev",
618 [WF_MAX_OPTS] = NULL,
619};
620
75c8b434
DC
621void
622libxfs_buftarg_init(
623 struct xfs_mount *mp,
624 dev_t dev,
625 dev_t logdev,
626 dev_t rtdev)
627{
704e4cef
DW
628 char *p = getenv("LIBXFS_DEBUG_WRITE_CRASH");
629 unsigned long dfail = 0, lfail = 0, rfail = 0;
630
631 /* Simulate utility crash after a certain number of writes. */
632 while (p && *p) {
633 char *val;
634
635 switch (getsubopt(&p, wf_opts, &val)) {
636 case WF_DATA:
637 if (!val) {
638 fprintf(stderr,
639 _("ddev write fail requires a parameter\n"));
640 exit(1);
641 }
642 dfail = strtoul(val, NULL, 0);
643 break;
644 case WF_LOG:
645 if (!val) {
646 fprintf(stderr,
647 _("logdev write fail requires a parameter\n"));
648 exit(1);
649 }
650 lfail = strtoul(val, NULL, 0);
651 break;
652 case WF_RT:
653 if (!val) {
654 fprintf(stderr,
655 _("rtdev write fail requires a parameter\n"));
656 exit(1);
657 }
658 rfail = strtoul(val, NULL, 0);
659 break;
660 default:
661 fprintf(stderr, _("unknown write fail type %s\n"),
662 val);
663 exit(1);
664 break;
665 }
666 }
667
75c8b434
DC
668 if (mp->m_ddev_targp) {
669 /* should already have all buftargs initialised */
ab434d12 670 if (mp->m_ddev_targp->bt_bdev != dev ||
75c8b434
DC
671 mp->m_ddev_targp->bt_mount != mp) {
672 fprintf(stderr,
673 _("%s: bad buftarg reinit, ddev\n"),
674 progname);
675 exit(1);
676 }
677 if (!logdev || logdev == dev) {
678 if (mp->m_logdev_targp != mp->m_ddev_targp) {
679 fprintf(stderr,
680 _("%s: bad buftarg reinit, ldev mismatch\n"),
681 progname);
682 exit(1);
683 }
ab434d12 684 } else if (mp->m_logdev_targp->bt_bdev != logdev ||
75c8b434
DC
685 mp->m_logdev_targp->bt_mount != mp) {
686 fprintf(stderr,
687 _("%s: bad buftarg reinit, logdev\n"),
688 progname);
689 exit(1);
690 }
ab434d12 691 if (rtdev && (mp->m_rtdev_targp->bt_bdev != rtdev ||
75c8b434
DC
692 mp->m_rtdev_targp->bt_mount != mp)) {
693 fprintf(stderr,
694 _("%s: bad buftarg reinit, rtdev\n"),
695 progname);
696 exit(1);
697 }
698 return;
699 }
700
704e4cef 701 mp->m_ddev_targp = libxfs_buftarg_alloc(mp, dev, dfail);
75c8b434
DC
702 if (!logdev || logdev == dev)
703 mp->m_logdev_targp = mp->m_ddev_targp;
704 else
704e4cef
DW
705 mp->m_logdev_targp = libxfs_buftarg_alloc(mp, logdev, lfail);
706 mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, rtdev, rfail);
75c8b434
DC
707}
708
2bd0ea18
NS
709/*
710 * Mount structure initialization, provides a filled-in xfs_mount_t
711 * such that the numerous XFS_* macros can be used. If dev is zero,
712 * no IO will be performed (no size checks, read root inodes).
713 */
d855bce8 714struct xfs_mount *
2bd0ea18 715libxfs_mount(
d855bce8
DW
716 struct xfs_mount *mp,
717 struct xfs_sb *sb,
718 dev_t dev,
719 dev_t logdev,
720 dev_t rtdev,
721 int flags)
2bd0ea18 722{
d855bce8
DW
723 struct xfs_buf *bp;
724 struct xfs_sb *sbp;
725 xfs_daddr_t d;
726 bool debugger = (flags & LIBXFS_MOUNT_DEBUGGER);
727 int error;
2bd0ea18 728
3bc1fdd4 729 mp->m_features = xfs_sb_version_to_features(sb);
75c8b434
DC
730 libxfs_buftarg_init(mp, dev, logdev, rtdev);
731
f747f7dd 732 mp->m_finobt_nores = true;
6239071d 733 mp->m_flags = (LIBXFS_MOUNT_32BITINODES|LIBXFS_MOUNT_32BITINOOPT);
0ee9753e 734 xfs_set_inode32(mp);
2bd0ea18 735 mp->m_sb = *sb;
56b2de80 736 INIT_RADIX_TREE(&mp->m_perag_tree, GFP_KERNEL);
686bddf9
DC
737 sbp = &mp->m_sb;
738 spin_lock_init(&mp->m_sb_lock);
739 spin_lock_init(&mp->m_agirotor_lock);
2bd0ea18 740
4896e6c8 741 xfs_sb_mount_common(mp, sb);
2bd0ea18 742
949c0f10
NS
743 /*
744 * Set whether we're using stripe alignment.
745 */
5e656dbb 746 if (xfs_sb_version_hasdalign(&mp->m_sb)) {
949c0f10
NS
747 mp->m_dalign = sbp->sb_unit;
748 mp->m_swidth = sbp->sb_width;
749 }
750
3a05ab22
DW
751 xfs_alloc_compute_maxlevels(mp);
752 xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
753 xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
754 xfs_ialloc_setup_geometry(mp);
755 xfs_rmapbt_compute_maxlevels(mp);
756 xfs_refcountbt_compute_maxlevels(mp);
2bd0ea18
NS
757
758 /*
759 * Check that the data (and log if separate) are an ok size.
760 */
9440d84d 761 d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
2bd0ea18 762 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
9440d84d 763 fprintf(stderr, _("%s: size check failed\n"), progname);
4ca431fc
NS
764 if (!(flags & LIBXFS_MOUNT_DEBUGGER))
765 return NULL;
2bd0ea18
NS
766 }
767
ff105f75
DC
768 /*
769 * We automatically convert v1 inodes to v2 inodes now, so if
770 * the NLINK bit is not set we can't operate on the filesystem.
771 */
772 if (!(sbp->sb_versionnum & XFS_SB_VERSION_NLINKBIT)) {
773
774 fprintf(stderr, _(
775 "%s: V1 inodes unsupported. Please try an older xfsprogs.\n"),
776 progname);
777 exit(1);
778 }
779
780 /* Check for supported directory formats */
781 if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT)) {
9a048535
DC
782
783 fprintf(stderr, _(
784 "%s: V1 directories unsupported. Please try an older xfsprogs.\n"),
785 progname);
786 exit(1);
5e656dbb 787 }
2bd0ea18 788
ff105f75
DC
789 /* check for unsupported other features */
790 if (!xfs_sb_good_version(sbp)) {
791 fprintf(stderr, _(
792 "%s: Unsupported features detected. Please try a newer xfsprogs.\n"),
793 progname);
794 exit(1);
795 }
796
797 xfs_da_mount(mp);
798
5e656dbb
BN
799 if (xfs_sb_version_hasattr2(&mp->m_sb))
800 mp->m_flags |= LIBXFS_MOUNT_ATTR2;
57c9fccb 801
2bd0ea18 802 /* Initialize the precomputed transaction reservations values */
5e656dbb 803 xfs_trans_init(mp);
2bd0ea18
NS
804
805 if (dev == 0) /* maxtrres, we have no device so leave now */
806 return mp;
807
d855bce8 808 /* device size checks must pass unless we're a debugger. */
31079e67
DW
809 error = libxfs_buf_read(mp->m_dev, d - XFS_FSS_TO_BB(mp, 1),
810 XFS_FSS_TO_BB(mp, 1), 0, &bp, NULL);
811 if (error) {
9440d84d 812 fprintf(stderr, _("%s: data size check failed\n"), progname);
d855bce8 813 if (!debugger)
4ca431fc 814 return NULL;
32244196 815 } else
e02ba985 816 libxfs_buf_relse(bp);
2bd0ea18 817
ab434d12
DC
818 if (mp->m_logdev_targp->bt_bdev &&
819 mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev) {
9440d84d 820 d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
31079e67
DW
821 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks ||
822 libxfs_buf_read(mp->m_logdev_targp,
823 d - XFS_FSB_TO_BB(mp, 1), XFS_FSB_TO_BB(mp, 1),
824 0, &bp, NULL)) {
9440d84d 825 fprintf(stderr, _("%s: log size checks failed\n"),
2bd0ea18 826 progname);
d855bce8 827 if (!debugger)
4ca431fc 828 return NULL;
2bd0ea18 829 }
32244196 830 if (bp)
e02ba985 831 libxfs_buf_relse(bp);
2bd0ea18
NS
832 }
833
834 /* Initialize realtime fields in the mount structure */
39798eb5 835 if (rtmount_init(mp, flags)) {
9440d84d
NS
836 fprintf(stderr, _("%s: realtime device init failed\n"),
837 progname);
4ca431fc 838 return NULL;
2bd0ea18
NS
839 }
840
a547152d
ES
841 /*
842 * libxfs_initialize_perag will allocate a perag structure for each ag.
843 * If agcount is corrupted and insanely high, this will OOM the box.
844 * If the agount seems (arbitrarily) high, try to read what would be
845 * the last AG, and if that fails for a relatively high agcount, just
846 * read the first one and let the user know to check the geometry.
847 */
848 if (sbp->sb_agcount > 1000000) {
31079e67 849 error = libxfs_buf_read(mp->m_dev,
a547152d 850 XFS_AG_DADDR(mp, sbp->sb_agcount - 1, 0), 1,
31079e67
DW
851 0, &bp, NULL);
852 if (error) {
a547152d
ES
853 fprintf(stderr, _("%s: read of AG %u failed\n"),
854 progname, sbp->sb_agcount);
d855bce8 855 if (!debugger)
a547152d
ES
856 return NULL;
857 fprintf(stderr, _("%s: limiting reads to AG 0\n"),
858 progname);
859 sbp->sb_agcount = 1;
31079e67
DW
860 } else
861 libxfs_buf_relse(bp);
a547152d
ES
862 }
863
56b2de80
DC
864 error = libxfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
865 if (error) {
866 fprintf(stderr, _("%s: perag init failed\n"),
867 progname);
2bd0ea18
NS
868 exit(1);
869 }
7bf9cd9d 870 mp->m_flags |= LIBXFS_MOUNT_PERAG_DATA_LOADED;
2bd0ea18 871
2bd0ea18
NS
872 return mp;
873}
874
f1b058f9
NS
875void
876libxfs_rtmount_destroy(xfs_mount_t *mp)
877{
878 if (mp->m_rsumip)
31845e4c 879 libxfs_irele(mp->m_rsumip);
f1b058f9 880 if (mp->m_rbmip)
31845e4c 881 libxfs_irele(mp->m_rbmip);
f1b058f9
NS
882 mp->m_rsumip = mp->m_rbmip = NULL;
883}
884
c335b673
DW
885/* Flush a device and report on writes that didn't make it to stable storage. */
886static inline int
887libxfs_flush_buftarg(
888 struct xfs_buftarg *btp,
889 const char *buftarg_descr)
890{
891 int error = 0;
892 int err2;
893
894 /*
895 * Write verifier failures are evidence of a buggy program. Make sure
896 * that this state is always reported to the caller.
897 */
898 if (btp->flags & XFS_BUFTARG_CORRUPT_WRITE) {
899 fprintf(stderr,
900_("%s: Refusing to write a corrupt buffer to the %s!\n"),
901 progname, buftarg_descr);
902 error = -EFSCORRUPTED;
903 }
904
905 if (btp->flags & XFS_BUFTARG_LOST_WRITE) {
906 fprintf(stderr,
907_("%s: Lost a write to the %s!\n"),
908 progname, buftarg_descr);
909 if (!error)
910 error = -EIO;
911 }
912
913 err2 = libxfs_blkdev_issue_flush(btp);
914 if (err2) {
915 fprintf(stderr,
916_("%s: Flushing the %s failed, err=%d!\n"),
917 progname, buftarg_descr, -err2);
918 }
919 if (!error)
920 error = err2;
921
922 return error;
923}
924
925/*
926 * Flush all dirty buffers to stable storage and report on writes that didn't
927 * make it to stable storage.
928 */
a7348c58 929int
c335b673
DW
930libxfs_flush_mount(
931 struct xfs_mount *mp)
932{
933 int error = 0;
934 int err2;
935
936 /*
a7348c58
DW
937 * Flush the buffer cache to write all dirty buffers to disk. Buffers
938 * that fail write verification will cause the CORRUPT_WRITE flag to be
939 * set in the buftarg. Buffers that cannot be written will cause the
940 * LOST_WRITE flag to be set in the buftarg. Once that's done,
941 * instruct the disks to persist their write caches.
c335b673 942 */
a7348c58 943 libxfs_bcache_flush();
c335b673
DW
944
945 /* Flush all kernel and disk write caches, and report failures. */
946 if (mp->m_ddev_targp) {
947 err2 = libxfs_flush_buftarg(mp->m_ddev_targp, _("data device"));
948 if (!error)
949 error = err2;
950 }
951
952 if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
953 err2 = libxfs_flush_buftarg(mp->m_logdev_targp,
954 _("log device"));
955 if (!error)
956 error = err2;
957 }
958
959 if (mp->m_rtdev_targp) {
960 err2 = libxfs_flush_buftarg(mp->m_rtdev_targp,
961 _("realtime device"));
962 if (!error)
963 error = err2;
964 }
965
966 return error;
967}
968
2bd0ea18 969/*
9440d84d 970 * Release any resource obtained during a mount.
2bd0ea18 971 */
c335b673
DW
972int
973libxfs_umount(
974 struct xfs_mount *mp)
2bd0ea18 975{
c335b673 976 int error;
56b2de80 977
f1b058f9 978 libxfs_rtmount_destroy(mp);
c335b673 979
a7348c58
DW
980 /*
981 * Purge the buffer cache to write all dirty buffers to disk and free
982 * all incore buffers, then pick up the outcome when we tell the disks
983 * to persist their write caches.
984 */
985 libxfs_bcache_purge();
c335b673 986 error = libxfs_flush_mount(mp);
f1b058f9 987
7bf9cd9d
DW
988 /*
989 * Only try to free the per-AG structures if we set them up in the
990 * first place.
991 */
4bcd30f6
DC
992 if (mp->m_flags & LIBXFS_MOUNT_PERAG_DATA_LOADED)
993 libxfs_free_perag(mp);
4334e2e8
ES
994
995 kmem_free(mp->m_attr_geo);
996 kmem_free(mp->m_dir_geo);
997
998 kmem_free(mp->m_rtdev_targp);
999 if (mp->m_logdev_targp != mp->m_ddev_targp)
1000 kmem_free(mp->m_logdev_targp);
1001 kmem_free(mp->m_ddev_targp);
f8149110 1002
c335b673 1003 return error;
2bd0ea18 1004}
f1b058f9
NS
1005
1006/*
1007 * Release any global resources used by libxfs.
1008 */
1009void
a9468486
DW
1010libxfs_destroy(
1011 struct libxfs_xinit *li)
f1b058f9 1012{
a9468486
DW
1013 int leaked;
1014
1015 libxfs_close_devices(li);
44488491 1016
864028ed
ES
1017 /* Free everything from the buffer cache before freeing buffer zone */
1018 libxfs_bcache_purge();
1019 libxfs_bcache_free();
f1b058f9 1020 cache_destroy(libxfs_bcache);
7a326ce0 1021 leaked = destroy_zones();
e4da1b16 1022 rcu_unregister_thread();
44488491
ES
1023 if (getenv("LIBXFS_LEAK_CHECK") && leaked)
1024 exit(1);
f1b058f9 1025}
9f38f08d 1026
b74a1f6a
NS
1027int
1028libxfs_device_alignment(void)
1029{
1030 return platform_align_blockdev();
1031}
1032
9f38f08d 1033void
b6281496 1034libxfs_report(FILE *fp)
9f38f08d 1035{
cb5b3ef4
MV
1036 time_t t;
1037 char *c;
1038
b6281496 1039 cache_report(fp, "libxfs_bcache", libxfs_bcache);
cb5b3ef4
MV
1040
1041 t = time(NULL);
1042 c = asctime(localtime(&t));
1043 fprintf(fp, "%s", c);
1044}