]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxfs/init.c
libxfs: remove libxfs_physmem
[thirdparty/xfsprogs-dev.git] / libxfs / init.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6
7 #include <sys/stat.h>
8 #include "init.h"
9
10 #include "libxfs_priv.h"
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"
17 #include "xfs_defer.h"
18 #include "xfs_inode_buf.h"
19 #include "xfs_inode_fork.h"
20 #include "xfs_inode.h"
21 #include "xfs_trans.h"
22 #include "xfs_rmap_btree.h"
23 #include "xfs_refcount_btree.h"
24
25 #include "libxfs.h" /* for now */
26
27 char *progname = "libxfs"; /* default, changed by each tool */
28
29 struct cache *libxfs_bcache; /* global buffer cache */
30 int libxfs_bhash_size; /* #buckets in bcache */
31
32 int use_xfs_buf_lock; /* global flag: use xfs_buf_t locks for MT */
33
34 /*
35 * dev_map - map open devices to fd.
36 */
37 #define MAX_DEVS 10 /* arbitary maximum */
38 static int nextfakedev = -1; /* device number to give to next fake device */
39 static struct dev_to_fd {
40 dev_t dev;
41 int fd;
42 } dev_map[MAX_DEVS]={{0}};
43
44 /*
45 * Checks whether a given device has a mounted, writable
46 * filesystem, returns 1 if it does & fatal (just warns
47 * if not fatal, but allows us to proceed).
48 *
49 * Useful to tools which will produce uncertain results
50 * if the filesystem is active - repair, check, logprint.
51 */
52 static int
53 check_isactive(char *name, char *block, int fatal)
54 {
55 struct stat st;
56
57 if (stat(block, &st) < 0)
58 return 0;
59 if ((st.st_mode & S_IFMT) != S_IFBLK)
60 return 0;
61 if (platform_check_ismounted(name, block, &st, 0) == 0)
62 return 0;
63 if (platform_check_iswritable(name, block, &st))
64 return fatal ? 1 : 0;
65 return 0;
66 }
67
68 /* libxfs_device_to_fd:
69 * lookup a device number in the device map
70 * return the associated fd
71 */
72 int
73 libxfs_device_to_fd(dev_t device)
74 {
75 int d;
76
77 for (d = 0; d < MAX_DEVS; d++)
78 if (dev_map[d].dev == device)
79 return dev_map[d].fd;
80
81 fprintf(stderr, _("%s: %s: device %lld is not open\n"),
82 progname, __FUNCTION__, (long long)device);
83 exit(1);
84 /* NOTREACHED */
85 }
86
87 /* libxfs_device_open:
88 * open a device and return its device number
89 */
90 dev_t
91 libxfs_device_open(char *path, int creat, int xflags, int setblksize)
92 {
93 dev_t dev;
94 int fd, d, flags;
95 int readonly, dio, excl;
96 struct stat statb;
97
98 readonly = (xflags & LIBXFS_ISREADONLY);
99 excl = (xflags & LIBXFS_EXCLUSIVELY) && !creat;
100 dio = (xflags & LIBXFS_DIRECT) && !creat && platform_direct_blockdev();
101
102 retry:
103 flags = (readonly ? O_RDONLY : O_RDWR) | \
104 (creat ? (O_CREAT|O_TRUNC) : 0) | \
105 (dio ? O_DIRECT : 0) | \
106 (excl ? O_EXCL : 0);
107
108 if ((fd = open(path, flags, 0666)) < 0) {
109 if (errno == EINVAL && --dio == 0)
110 goto retry;
111 fprintf(stderr, _("%s: cannot open %s: %s\n"),
112 progname, path, strerror(errno));
113 exit(1);
114 }
115
116 if (fstat(fd, &statb) < 0) {
117 fprintf(stderr, _("%s: cannot stat %s: %s\n"),
118 progname, path, strerror(errno));
119 exit(1);
120 }
121
122 if (!readonly && setblksize && (statb.st_mode & S_IFMT) == S_IFBLK) {
123 if (setblksize == 1)
124 /* use the default blocksize */
125 (void)platform_set_blocksize(fd, path, statb.st_rdev, XFS_MIN_SECTORSIZE, 0);
126 else {
127 /* given an explicit blocksize to use */
128 if (platform_set_blocksize(fd, path, statb.st_rdev, setblksize, 1))
129 exit(1);
130 }
131 }
132
133 /*
134 * Get the device number from the stat buf - unless
135 * we're not opening a real device, in which case
136 * choose a new fake device number.
137 */
138 dev = (statb.st_rdev) ? (statb.st_rdev) : (nextfakedev--);
139
140 for (d = 0; d < MAX_DEVS; d++)
141 if (dev_map[d].dev == dev) {
142 fprintf(stderr, _("%s: device %lld is already open\n"),
143 progname, (long long)dev);
144 exit(1);
145 }
146
147 for (d = 0; d < MAX_DEVS; d++)
148 if (!dev_map[d].dev) {
149 dev_map[d].dev = dev;
150 dev_map[d].fd = fd;
151
152 return dev;
153 }
154
155 fprintf(stderr, _("%s: %s: too many open devices\n"),
156 progname, __FUNCTION__);
157 exit(1);
158 /* NOTREACHED */
159 }
160
161 void
162 libxfs_device_close(dev_t dev)
163 {
164 int d;
165
166 for (d = 0; d < MAX_DEVS; d++)
167 if (dev_map[d].dev == dev) {
168 int fd;
169
170 fd = dev_map[d].fd;
171 dev_map[d].dev = dev_map[d].fd = 0;
172
173 fsync(fd);
174 platform_flush_device(fd, dev);
175 close(fd);
176
177 return;
178 }
179
180 fprintf(stderr, _("%s: %s: device %lld is not open\n"),
181 progname, __FUNCTION__, (long long)dev);
182 exit(1);
183 }
184
185 static int
186 check_open(char *path, int flags, char **rawfile, char **blockfile)
187 {
188 int readonly = (flags & LIBXFS_ISREADONLY);
189 int inactive = (flags & LIBXFS_ISINACTIVE);
190 int dangerously = (flags & LIBXFS_DANGEROUSLY);
191 struct stat stbuf;
192
193 if (stat(path, &stbuf) < 0) {
194 perror(path);
195 return 0;
196 }
197 if (!(*rawfile = platform_findrawpath(path))) {
198 fprintf(stderr, _("%s: "
199 "can't find a character device matching %s\n"),
200 progname, path);
201 return 0;
202 }
203 if (!(*blockfile = platform_findblockpath(path))) {
204 fprintf(stderr, _("%s: "
205 "can't find a block device matching %s\n"),
206 progname, path);
207 return 0;
208 }
209 if (!readonly && !inactive && platform_check_ismounted(path, *blockfile, NULL, 1))
210 return 0;
211
212 if (inactive && check_isactive(path, *blockfile, ((readonly|dangerously)?1:0)))
213 return 0;
214
215 return 1;
216 }
217
218 /*
219 * Initialize/destroy all of the zone allocators we use.
220 */
221 static void
222 init_zones(void)
223 {
224 /* initialise zone allocation */
225 xfs_buf_zone = kmem_zone_init(sizeof(struct xfs_buf), "xfs_buffer");
226 xfs_inode_zone = kmem_zone_init(sizeof(struct xfs_inode), "xfs_inode");
227 xfs_ifork_zone = kmem_zone_init(sizeof(struct xfs_ifork), "xfs_ifork");
228 xfs_ili_zone = kmem_zone_init(
229 sizeof(struct xfs_inode_log_item),"xfs_inode_log_item");
230 xfs_buf_item_zone = kmem_zone_init(
231 sizeof(struct xfs_buf_log_item), "xfs_buf_log_item");
232 xfs_da_state_zone = kmem_zone_init(
233 sizeof(struct xfs_da_state), "xfs_da_state");
234 xfs_btree_cur_zone = kmem_zone_init(
235 sizeof(struct xfs_btree_cur), "xfs_btree_cur");
236 xfs_bmap_free_item_zone = kmem_zone_init(
237 sizeof(struct xfs_extent_free_item),
238 "xfs_bmap_free_item");
239 xfs_trans_zone = kmem_zone_init(
240 sizeof(struct xfs_trans), "xfs_trans");
241 }
242
243 static int
244 destroy_zones(void)
245 {
246 int leaked = 0;
247
248 leaked += kmem_zone_destroy(xfs_buf_zone);
249 leaked += kmem_zone_destroy(xfs_ili_zone);
250 leaked += kmem_zone_destroy(xfs_inode_zone);
251 leaked += kmem_zone_destroy(xfs_ifork_zone);
252 leaked += kmem_zone_destroy(xfs_buf_item_zone);
253 leaked += kmem_zone_destroy(xfs_da_state_zone);
254 leaked += kmem_zone_destroy(xfs_btree_cur_zone);
255 leaked += kmem_zone_destroy(xfs_bmap_free_item_zone);
256 leaked += kmem_zone_destroy(xfs_trans_zone);
257
258 return leaked;
259 }
260
261 /*
262 * libxfs initialization.
263 * Caller gets a 0 on failure (and we print a message), 1 on success.
264 */
265 int
266 libxfs_init(libxfs_init_t *a)
267 {
268 char *blockfile;
269 char *dname;
270 char dpath[25];
271 int fd;
272 char *logname;
273 char logpath[25];
274 char *rawfile;
275 char *rtname;
276 char rtpath[25];
277 int rval = 0;
278 int flags;
279
280 dpath[0] = logpath[0] = rtpath[0] = '\0';
281 dname = a->dname;
282 logname = a->logname;
283 rtname = a->rtname;
284 a->dfd = a->logfd = a->rtfd = -1;
285 a->ddev = a->logdev = a->rtdev = 0;
286 a->dsize = a->lbsize = a->rtbsize = 0;
287 a->dbsize = a->logBBsize = a->logBBstart = a->rtsize = 0;
288
289 fd = -1;
290 flags = (a->isreadonly | a->isdirect);
291
292 radix_tree_init();
293
294 if (a->volname) {
295 if(!check_open(a->volname,flags,&rawfile,&blockfile))
296 goto done;
297 fd = open(rawfile, O_RDONLY);
298 dname = a->dname = a->volname;
299 a->volname = NULL;
300 }
301 if (dname) {
302 if (a->disfile) {
303 a->ddev= libxfs_device_open(dname, a->dcreat, flags,
304 a->setblksize);
305 a->dfd = libxfs_device_to_fd(a->ddev);
306 platform_findsizes(dname, a->dfd, &a->dsize,
307 &a->dbsize);
308 } else {
309 if (!check_open(dname, flags, &rawfile, &blockfile))
310 goto done;
311 a->ddev = libxfs_device_open(rawfile,
312 a->dcreat, flags, a->setblksize);
313 a->dfd = libxfs_device_to_fd(a->ddev);
314 platform_findsizes(rawfile, a->dfd,
315 &a->dsize, &a->dbsize);
316 }
317 } else
318 a->dsize = 0;
319 if (logname) {
320 if (a->lisfile) {
321 a->logdev = libxfs_device_open(logname,
322 a->lcreat, flags, a->setblksize);
323 a->logfd = libxfs_device_to_fd(a->logdev);
324 platform_findsizes(dname, a->logfd, &a->logBBsize,
325 &a->lbsize);
326 } else {
327 if (!check_open(logname, flags, &rawfile, &blockfile))
328 goto done;
329 a->logdev = libxfs_device_open(rawfile,
330 a->lcreat, flags, a->setblksize);
331 a->logfd = libxfs_device_to_fd(a->logdev);
332 platform_findsizes(rawfile, a->logfd,
333 &a->logBBsize, &a->lbsize);
334 }
335 } else
336 a->logBBsize = 0;
337 if (rtname) {
338 if (a->risfile) {
339 a->rtdev = libxfs_device_open(rtname,
340 a->rcreat, flags, a->setblksize);
341 a->rtfd = libxfs_device_to_fd(a->rtdev);
342 platform_findsizes(dname, a->rtfd, &a->rtsize,
343 &a->rtbsize);
344 } else {
345 if (!check_open(rtname, flags, &rawfile, &blockfile))
346 goto done;
347 a->rtdev = libxfs_device_open(rawfile,
348 a->rcreat, flags, a->setblksize);
349 a->rtfd = libxfs_device_to_fd(a->rtdev);
350 platform_findsizes(rawfile, a->rtfd,
351 &a->rtsize, &a->rtbsize);
352 }
353 } else
354 a->rtsize = 0;
355 if (a->dsize < 0) {
356 fprintf(stderr, _("%s: can't get size for data subvolume\n"),
357 progname);
358 goto done;
359 }
360 if (a->logBBsize < 0) {
361 fprintf(stderr, _("%s: can't get size for log subvolume\n"),
362 progname);
363 goto done;
364 }
365 if (a->rtsize < 0) {
366 fprintf(stderr, _("%s: can't get size for realtime subvolume\n"),
367 progname);
368 goto done;
369 }
370 if (!libxfs_bhash_size)
371 libxfs_bhash_size = LIBXFS_BHASHSIZE(sbp);
372 libxfs_bcache = cache_init(a->bcache_flags, libxfs_bhash_size,
373 &libxfs_bcache_operations);
374 use_xfs_buf_lock = a->usebuflock;
375 xfs_dir_startup();
376 init_zones();
377 rval = 1;
378 done:
379 if (dpath[0])
380 unlink(dpath);
381 if (logpath[0])
382 unlink(logpath);
383 if (rtpath[0])
384 unlink(rtpath);
385 if (fd >= 0)
386 close(fd);
387 if (!rval && a->ddev)
388 libxfs_device_close(a->ddev);
389 if (!rval && a->logdev)
390 libxfs_device_close(a->logdev);
391 if (!rval && a->rtdev)
392 libxfs_device_close(a->rtdev);
393 return rval;
394 }
395
396
397 /*
398 * Initialize realtime fields in the mount structure.
399 */
400 static int
401 rtmount_init(
402 xfs_mount_t *mp, /* file system mount structure */
403 int flags)
404 {
405 xfs_buf_t *bp; /* buffer for last block of subvolume */
406 xfs_daddr_t d; /* address of last block of subvolume */
407 xfs_sb_t *sbp; /* filesystem superblock copy in mount */
408
409 sbp = &mp->m_sb;
410 if (sbp->sb_rblocks == 0)
411 return 0;
412 if (mp->m_rtdev_targp->dev == 0 && !(flags & LIBXFS_MOUNT_DEBUGGER)) {
413 fprintf(stderr, _("%s: filesystem has a realtime subvolume\n"),
414 progname);
415 return -1;
416 }
417 mp->m_rsumlevels = sbp->sb_rextslog + 1;
418 mp->m_rsumsize =
419 (uint)sizeof(xfs_suminfo_t) * mp->m_rsumlevels *
420 sbp->sb_rbmblocks;
421 mp->m_rsumsize = roundup(mp->m_rsumsize, sbp->sb_blocksize);
422 mp->m_rbmip = mp->m_rsumip = NULL;
423
424 /*
425 * Allow debugger to be run without the realtime device present.
426 */
427 if (flags & LIBXFS_MOUNT_DEBUGGER)
428 return 0;
429
430 /*
431 * Check that the realtime section is an ok size.
432 */
433 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks);
434 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_rblocks) {
435 fprintf(stderr, _("%s: realtime init - %llu != %llu\n"),
436 progname, (unsigned long long) XFS_BB_TO_FSB(mp, d),
437 (unsigned long long) mp->m_sb.sb_rblocks);
438 return -1;
439 }
440 bp = libxfs_readbuf(mp->m_rtdev,
441 d - XFS_FSB_TO_BB(mp, 1), XFS_FSB_TO_BB(mp, 1), 0, NULL);
442 if (bp == NULL) {
443 fprintf(stderr, _("%s: realtime size check failed\n"),
444 progname);
445 return -1;
446 }
447 libxfs_putbuf(bp);
448 return 0;
449 }
450
451 static int
452 libxfs_initialize_perag(
453 xfs_mount_t *mp,
454 xfs_agnumber_t agcount,
455 xfs_agnumber_t *maxagi)
456 {
457 xfs_agnumber_t index, max_metadata;
458 xfs_agnumber_t first_initialised = 0;
459 xfs_perag_t *pag;
460 xfs_agino_t agino;
461 xfs_ino_t ino;
462 xfs_sb_t *sbp = &mp->m_sb;
463 int error = -ENOMEM;
464
465 /*
466 * Walk the current per-ag tree so we don't try to initialise AGs
467 * that already exist (growfs case). Allocate and insert all the
468 * AGs we don't find ready for initialisation.
469 */
470 for (index = 0; index < agcount; index++) {
471 pag = xfs_perag_get(mp, index);
472 if (pag) {
473 xfs_perag_put(pag);
474 continue;
475 }
476 if (!first_initialised)
477 first_initialised = index;
478
479 pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL);
480 if (!pag)
481 goto out_unwind;
482 pag->pag_agno = index;
483 pag->pag_mount = mp;
484
485 if (radix_tree_insert(&mp->m_perag_tree, index, pag)) {
486 error = -EEXIST;
487 goto out_unwind;
488 }
489 }
490
491 /*
492 * If we mount with the inode64 option, or no inode overflows
493 * the legacy 32-bit address space clear the inode32 option.
494 */
495 agino = XFS_AGB_TO_AGINO(mp, sbp->sb_agblocks - 1);
496 ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
497
498 if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32)
499 mp->m_flags |= XFS_MOUNT_32BITINODES;
500 else
501 mp->m_flags &= ~XFS_MOUNT_32BITINODES;
502
503 if (mp->m_flags & XFS_MOUNT_32BITINODES) {
504 /*
505 * Calculate how much should be reserved for inodes to meet
506 * the max inode percentage.
507 */
508 if (M_IGEO(mp)->maxicount) {
509 uint64_t icount;
510
511 icount = sbp->sb_dblocks * sbp->sb_imax_pct;
512 do_div(icount, 100);
513 icount += sbp->sb_agblocks - 1;
514 do_div(icount, sbp->sb_agblocks);
515 max_metadata = icount;
516 } else {
517 max_metadata = agcount;
518 }
519
520 for (index = 0; index < agcount; index++) {
521 ino = XFS_AGINO_TO_INO(mp, index, agino);
522 if (ino > XFS_MAXINUMBER_32) {
523 index++;
524 break;
525 }
526
527 pag = xfs_perag_get(mp, index);
528 pag->pagi_inodeok = 1;
529 if (index < max_metadata)
530 pag->pagf_metadata = 1;
531 xfs_perag_put(pag);
532 }
533 } else {
534 for (index = 0; index < agcount; index++) {
535 pag = xfs_perag_get(mp, index);
536 pag->pagi_inodeok = 1;
537 xfs_perag_put(pag);
538 }
539 }
540
541 if (maxagi)
542 *maxagi = index;
543
544 mp->m_ag_prealloc_blocks = xfs_prealloc_blocks(mp);
545 return 0;
546
547 out_unwind:
548 kmem_free(pag);
549 for (; index > first_initialised; index--) {
550 pag = radix_tree_delete(&mp->m_perag_tree, index);
551 kmem_free(pag);
552 }
553 return error;
554 }
555
556 static struct xfs_buftarg *
557 libxfs_buftarg_alloc(
558 struct xfs_mount *mp,
559 dev_t dev)
560 {
561 struct xfs_buftarg *btp;
562
563 btp = malloc(sizeof(*btp));
564 if (!btp) {
565 fprintf(stderr, _("%s: buftarg init failed\n"),
566 progname);
567 exit(1);
568 }
569 btp->bt_mount = mp;
570 btp->dev = dev;
571 return btp;
572 }
573
574 void
575 libxfs_buftarg_init(
576 struct xfs_mount *mp,
577 dev_t dev,
578 dev_t logdev,
579 dev_t rtdev)
580 {
581 if (mp->m_ddev_targp) {
582 /* should already have all buftargs initialised */
583 if (mp->m_ddev_targp->dev != dev ||
584 mp->m_ddev_targp->bt_mount != mp) {
585 fprintf(stderr,
586 _("%s: bad buftarg reinit, ddev\n"),
587 progname);
588 exit(1);
589 }
590 if (!logdev || logdev == dev) {
591 if (mp->m_logdev_targp != mp->m_ddev_targp) {
592 fprintf(stderr,
593 _("%s: bad buftarg reinit, ldev mismatch\n"),
594 progname);
595 exit(1);
596 }
597 } else if (mp->m_logdev_targp->dev != logdev ||
598 mp->m_logdev_targp->bt_mount != mp) {
599 fprintf(stderr,
600 _("%s: bad buftarg reinit, logdev\n"),
601 progname);
602 exit(1);
603 }
604 if (rtdev && (mp->m_rtdev_targp->dev != rtdev ||
605 mp->m_rtdev_targp->bt_mount != mp)) {
606 fprintf(stderr,
607 _("%s: bad buftarg reinit, rtdev\n"),
608 progname);
609 exit(1);
610 }
611 return;
612 }
613
614 mp->m_ddev_targp = libxfs_buftarg_alloc(mp, dev);
615 if (!logdev || logdev == dev)
616 mp->m_logdev_targp = mp->m_ddev_targp;
617 else
618 mp->m_logdev_targp = libxfs_buftarg_alloc(mp, logdev);
619 mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, rtdev);
620 }
621
622 /*
623 * Mount structure initialization, provides a filled-in xfs_mount_t
624 * such that the numerous XFS_* macros can be used. If dev is zero,
625 * no IO will be performed (no size checks, read root inodes).
626 */
627 xfs_mount_t *
628 libxfs_mount(
629 xfs_mount_t *mp,
630 xfs_sb_t *sb,
631 dev_t dev,
632 dev_t logdev,
633 dev_t rtdev,
634 int flags)
635 {
636 xfs_daddr_t d;
637 xfs_buf_t *bp;
638 xfs_sb_t *sbp;
639 int error;
640
641 libxfs_buftarg_init(mp, dev, logdev, rtdev);
642
643 mp->m_finobt_nores = true;
644 mp->m_flags = (LIBXFS_MOUNT_32BITINODES|LIBXFS_MOUNT_32BITINOOPT);
645 mp->m_sb = *sb;
646 INIT_RADIX_TREE(&mp->m_perag_tree, GFP_KERNEL);
647 sbp = &(mp->m_sb);
648
649 xfs_sb_mount_common(mp, sb);
650
651 /*
652 * Set whether we're using stripe alignment.
653 */
654 if (xfs_sb_version_hasdalign(&mp->m_sb)) {
655 mp->m_dalign = sbp->sb_unit;
656 mp->m_swidth = sbp->sb_width;
657 }
658
659 xfs_alloc_compute_maxlevels(mp);
660 xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
661 xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
662 xfs_ialloc_setup_geometry(mp);
663 xfs_rmapbt_compute_maxlevels(mp);
664 xfs_refcountbt_compute_maxlevels(mp);
665
666 /*
667 * Check that the data (and log if separate) are an ok size.
668 */
669 d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
670 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
671 fprintf(stderr, _("%s: size check failed\n"), progname);
672 if (!(flags & LIBXFS_MOUNT_DEBUGGER))
673 return NULL;
674 }
675
676 /*
677 * We automatically convert v1 inodes to v2 inodes now, so if
678 * the NLINK bit is not set we can't operate on the filesystem.
679 */
680 if (!(sbp->sb_versionnum & XFS_SB_VERSION_NLINKBIT)) {
681
682 fprintf(stderr, _(
683 "%s: V1 inodes unsupported. Please try an older xfsprogs.\n"),
684 progname);
685 exit(1);
686 }
687
688 /* Check for supported directory formats */
689 if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT)) {
690
691 fprintf(stderr, _(
692 "%s: V1 directories unsupported. Please try an older xfsprogs.\n"),
693 progname);
694 exit(1);
695 }
696
697 /* check for unsupported other features */
698 if (!xfs_sb_good_version(sbp)) {
699 fprintf(stderr, _(
700 "%s: Unsupported features detected. Please try a newer xfsprogs.\n"),
701 progname);
702 exit(1);
703 }
704
705 xfs_da_mount(mp);
706
707 if (xfs_sb_version_hasattr2(&mp->m_sb))
708 mp->m_flags |= LIBXFS_MOUNT_ATTR2;
709
710 /* Initialize the precomputed transaction reservations values */
711 xfs_trans_init(mp);
712
713 if (dev == 0) /* maxtrres, we have no device so leave now */
714 return mp;
715
716 bp = libxfs_readbuf(mp->m_dev,
717 d - XFS_FSS_TO_BB(mp, 1), XFS_FSS_TO_BB(mp, 1),
718 !(flags & LIBXFS_MOUNT_DEBUGGER), NULL);
719 if (!bp) {
720 fprintf(stderr, _("%s: data size check failed\n"), progname);
721 if (!(flags & LIBXFS_MOUNT_DEBUGGER))
722 return NULL;
723 } else
724 libxfs_putbuf(bp);
725
726 if (mp->m_logdev_targp->dev &&
727 mp->m_logdev_targp->dev != mp->m_ddev_targp->dev) {
728 d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
729 if ( (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) ||
730 (!(bp = libxfs_readbuf(mp->m_logdev_targp,
731 d - XFS_FSB_TO_BB(mp, 1),
732 XFS_FSB_TO_BB(mp, 1),
733 !(flags & LIBXFS_MOUNT_DEBUGGER), NULL))) ) {
734 fprintf(stderr, _("%s: log size checks failed\n"),
735 progname);
736 if (!(flags & LIBXFS_MOUNT_DEBUGGER))
737 return NULL;
738 }
739 if (bp)
740 libxfs_putbuf(bp);
741 }
742
743 /* Initialize realtime fields in the mount structure */
744 if (rtmount_init(mp, flags)) {
745 fprintf(stderr, _("%s: realtime device init failed\n"),
746 progname);
747 return NULL;
748 }
749
750 /*
751 * libxfs_initialize_perag will allocate a perag structure for each ag.
752 * If agcount is corrupted and insanely high, this will OOM the box.
753 * If the agount seems (arbitrarily) high, try to read what would be
754 * the last AG, and if that fails for a relatively high agcount, just
755 * read the first one and let the user know to check the geometry.
756 */
757 if (sbp->sb_agcount > 1000000) {
758 bp = libxfs_readbuf(mp->m_dev,
759 XFS_AG_DADDR(mp, sbp->sb_agcount - 1, 0), 1,
760 !(flags & LIBXFS_MOUNT_DEBUGGER), NULL);
761 if (bp->b_error) {
762 fprintf(stderr, _("%s: read of AG %u failed\n"),
763 progname, sbp->sb_agcount);
764 if (!(flags & LIBXFS_MOUNT_DEBUGGER))
765 return NULL;
766 fprintf(stderr, _("%s: limiting reads to AG 0\n"),
767 progname);
768 sbp->sb_agcount = 1;
769 }
770 libxfs_putbuf(bp);
771 }
772
773 error = libxfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
774 if (error) {
775 fprintf(stderr, _("%s: perag init failed\n"),
776 progname);
777 exit(1);
778 }
779
780 return mp;
781 }
782
783 void
784 libxfs_rtmount_destroy(xfs_mount_t *mp)
785 {
786 if (mp->m_rsumip)
787 libxfs_irele(mp->m_rsumip);
788 if (mp->m_rbmip)
789 libxfs_irele(mp->m_rbmip);
790 mp->m_rsumip = mp->m_rbmip = NULL;
791 }
792
793 /*
794 * Release any resource obtained during a mount.
795 */
796 void
797 libxfs_umount(xfs_mount_t *mp)
798 {
799 struct xfs_perag *pag;
800 int agno;
801
802 libxfs_rtmount_destroy(mp);
803 libxfs_bcache_purge();
804
805 for (agno = 0; agno < mp->m_maxagi; agno++) {
806 pag = radix_tree_delete(&mp->m_perag_tree, agno);
807 kmem_free(pag);
808 }
809
810 kmem_free(mp->m_attr_geo);
811 kmem_free(mp->m_dir_geo);
812
813 kmem_free(mp->m_rtdev_targp);
814 if (mp->m_logdev_targp != mp->m_ddev_targp)
815 kmem_free(mp->m_logdev_targp);
816 kmem_free(mp->m_ddev_targp);
817
818 }
819
820 /*
821 * Release any global resources used by libxfs.
822 */
823 void
824 libxfs_destroy(void)
825 {
826 int leaked;
827
828 /* Free everything from the buffer cache before freeing buffer zone */
829 libxfs_bcache_purge();
830 libxfs_bcache_free();
831 cache_destroy(libxfs_bcache);
832 leaked = destroy_zones();
833 if (getenv("LIBXFS_LEAK_CHECK") && leaked)
834 exit(1);
835 }
836
837 int
838 libxfs_device_alignment(void)
839 {
840 return platform_align_blockdev();
841 }
842
843 void
844 libxfs_report(FILE *fp)
845 {
846 time_t t;
847 char *c;
848
849 cache_report(fp, "libxfs_bcache", libxfs_bcache);
850
851 t = time(NULL);
852 c = asctime(localtime(&t));
853 fprintf(fp, "%s", c);
854 }