]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - libxfs/init.c
reenable use of direct IO now that DIOCINFO and O_DIRECT are working.
[thirdparty/xfsprogs-dev.git] / libxfs / init.c
CommitLineData
2bd0ea18
NS
1/*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33#define ustat __kernel_ustat
34#include <libxfs.h>
35#include <fcntl.h>
36#include <errno.h>
37#include <mntent.h>
38#include <sys/stat.h>
39#undef ustat
40#include <sys/ustat.h>
41#include <sys/ioctl.h>
42#include <sys/mount.h>
43
44#ifndef BLKSETSIZE /* Baaad m'kay, but it's not in libc yet */
45#define BLKSETSIZE _IO(0x12,108) /* set device block size */
46#endif
47
48#define findrawpath(x) x
49#define findblockpath(x) x
50
51char *progname = "libxfs"; /* default, changed by each tool */
52
53/*
54 * dev_map - map open devices to fd.
55 */
56#define MAX_DEVS 10 /* arbitary maximum */
57int nextfakedev = -1; /* device number to give to next fake device */
58static struct dev_to_fd {
59 dev_t dev;
60 int fd;
61} dev_map[MAX_DEVS]={{0}};
62
63static int
64check_ismounted(char *name, char *block, int verbose)
65{
66 struct ustat ust;
67 struct stat64 st;
68
69 if (stat64(block, &st) < 0)
70 return 0;
71 if ((st.st_mode & S_IFMT) != S_IFBLK)
72 return 0;
73 if (ustat(st.st_rdev, &ust) >= 0) {
74 if (verbose)
75 fprintf(stderr,
76 "%s: %s contains a mounted filesystem\n",
77 progname, name);
78 return 1;
79 }
80 return 0;
81}
82
83/*
84 * Checks whether a given device has a mounted, writable
85 * filesystem, returns 1 if it does & fatal (just warns
86 * if not fatal, but allows us to proceed).
87 *
88 * Useful to tools which will produce uncertain results
89 * if the filesystem is active - repair, check, logprint.
90 */
91static int
92check_isactive(char *name, char *block, int fatal)
93{
94 int sts = 0;
95 FILE *f;
96 struct mntent *mnt;
97
98 if (check_ismounted(name, block, 0)) {
99 if ((f = setmntent(MOUNTED, "r")) == NULL) {
100 fprintf(stderr,
101 "%s: %s contains a possibly writable, mounted "
102 "filesystem\n", progname, name);
103 return fatal;
104 }
105 while ((mnt = getmntent(f)) != NULL) {
106 if (hasmntopt(mnt, MNTOPT_RO) != NULL)
107 break;
108 }
109 if (mnt == NULL) {
110 fprintf(stderr,
111 "%s: %s contains a writable mounted "
112 "filesystem\n", progname, name);
113 sts = fatal;
114 }
115 endmntent(f);
116 }
117 return sts;
118}
119
120static __int64_t
121findsize(char *path)
122{
123 int fd;
124 int error;
125 long size;
126 struct stat64 st;
127
128 /* Test to see if we are dealing with a regular file rather than a
129 * block device, if we are just use the size returned by stat64
130 */
131 if (stat64(path, &st) < 0) {
132 fprintf(stderr, "%s: "
133 "cannot stat the device special file \"%s\": %s\n",
134 progname, path, strerror(errno));
135 exit(1);
136 }
137 if ((st.st_mode & S_IFMT) == S_IFREG) {
138 return (__int64_t)(st.st_size >> 9);
139 }
140
141 if ((fd = open(path, 0)) < 0) {
142 fprintf(stderr, "%s: "
143 "error opening the device special file \"%s\": %s\n",
144 progname, path, strerror(errno));
145 exit(1);
146 }
147 error = ioctl(fd, BLKGETSIZE, &size);
148 if (error < 0) {
149 fprintf(stderr, "%s: can't determine device size\n", progname);
150 exit(1);
151 }
152
153 close(fd);
154
155 return (__int64_t)size;
156}
157
158
159/* libxfs_device_to_fd:
160 * lookup a device number in the device map
161 * return the associated fd
162 */
163int
164libxfs_device_to_fd(dev_t device)
165{
166 int d;
167
168 for (d=0;d<MAX_DEVS;d++)
169 if (dev_map[d].dev == device)
170 return dev_map[d].fd;
171
172 fprintf(stderr, "%s: device_to_fd: device %Ld is not open\n",
173 progname, device);
174 exit(1);
175}
176
177/* libxfs_device_open:
178 * open a device and return its device number
179 */
180dev_t
181libxfs_device_open(char *path, int creat, int readonly)
182{
183 int fd;
184 dev_t dev;
185 int d;
186 struct stat statb;
187 int blocksize = 512; /* bytes */
188
189 if ((fd = open(path,
190 (readonly ? O_RDONLY : O_RDWR) |
191 (creat ? O_CREAT|O_TRUNC : 0),
192 0666)) < 0) {
193 fprintf(stderr, "%s: cannot open %s: %s\n",
194 progname, path, strerror(errno));
195 exit(1);
196 }
197
198 if (stat(path, &statb)<0) {
199 fprintf(stderr, "%s: cannot stat %s: %s\n",
200 progname, path, strerror(errno));
201 exit(1);
202 }
203
204 /* Set device blocksize to 512 bytes */
205 if ((statb.st_mode & S_IFMT) == S_IFBLK) {
206 if (ioctl(fd, BLKSETSIZE, &blocksize) < 0) {
207 fprintf(stderr, "%s: warning - cannot set blocksize on "
208 "block device %s: %s\n",
209 progname, path, strerror(errno));
210 }
211 }
212
213 /* get the device number from the stat buf - unless
214 * we're not opening a real device, in which case
215 * choose a new fake device number
216 */
217 dev=(statb.st_rdev)?(statb.st_rdev):(nextfakedev--);
218
219 for (d=0;d<MAX_DEVS;d++)
220 if (dev_map[d].dev == dev) {
221 fprintf(stderr, "%s: device %Ld is already open\n",
222 progname, dev);
223 exit(1);
224 }
225
226 for (d=0;d<MAX_DEVS;d++)
227 if (!dev_map[d].dev) {
228 dev_map[d].dev=dev;
229 dev_map[d].fd=fd;
230
231 return dev;
232 }
233
234 fprintf(stderr, "%s: device_open: too many open devices\n", progname);
235 exit(1);
236}
237
238void
239libxfs_device_close(dev_t dev)
240{
241 int d;
242
243 for (d=0;d<MAX_DEVS;d++)
244 if (dev_map[d].dev == dev) {
245 int fd;
246
247 fd=dev_map[d].dev;
248 dev_map[d].dev=dev_map[d].fd=0;
249
250 fsync(fd);
251 ioctl(fd, BLKFLSBUF, 0);
252 close(fd);
253
254 return;
255 }
256
257 fprintf(stderr, "%s: device_close: device %Ld is not open\n",
258 progname, dev);
259 ASSERT(0);
260 exit(1);
261}
262
263
264/*
265 * libxfs initialization.
266 * Caller gets a 0 on failure (and we print a message), 1 on success.
267 */
268int
269libxfs_init(libxfs_init_t *a)
270{
271 char *blockfile;
272 char curdir[MAXPATHLEN];
273 char *dname;
274 char dpath[25];
275 int fd;
276 char *logname;
277 char logpath[25];
278 int needcd;
279 char *rawfile;
280 char *rtname;
281 char rtpath[25];
282 int rval = 0;
283 int readonly;
284 int inactive;
285 struct stat64 stbuf;
286
287 dpath[0] = logpath[0] = rtpath[0] = '\0';
288 dname = a->dname;
289 logname = a->logname;
290 rtname = a->rtname;
291 a->ddev = a->logdev = a->rtdev = 0;
292 a->dfd = a->logfd = a->rtfd = -1;
293 a->dsize = a->logBBsize = a->logBBstart = a->rtsize = 0;
294
295 (void)getcwd(curdir,MAXPATHLEN);
296 needcd = 0;
297 fd = -1;
298 readonly = (a->isreadonly & LIBXFS_ISREADONLY);
299 inactive = (a->isreadonly & LIBXFS_ISINACTIVE);
300 if (a->volname) {
301 if (stat64(a->volname, &stbuf) < 0) {
302 perror(a->volname);
303 goto done;
304 }
305 if (!(rawfile = findrawpath(a->volname))) {
306 fprintf(stderr, "%s: "
307 "can't find a character device matching %s\n",
308 progname, a->volname);
309 goto done;
310 }
311 if (!(blockfile = findblockpath(a->volname))) {
312 fprintf(stderr, "%s: "
313 "can't find a block device matching %s\n",
314 progname, a->volname);
315 goto done;
316 }
317 if (!readonly && !inactive && check_ismounted(
318 a->volname, blockfile, 1))
319 goto done;
320 if (inactive && check_isactive(
321 a->volname, blockfile, readonly))
322 goto done;
323 needcd = 1;
324 fd = open(rawfile, O_RDONLY);
325#ifdef HAVE_VOLUME_MANAGER
326 xlv_getdev_t getdev;
327 if (ioctl(fd, DIOCGETVOLDEV, &getdev) < 0)
328#else
329 if (1)
330#endif
331 {
332 if (a->notvolok) {
333 dname = a->dname = a->volname;
334 a->volname = NULL;
335 goto voldone;
336 }
337 fprintf(stderr, "%s: "
338 "%s is not a volume device name\n",
339 progname, a->volname);
340 if (a->notvolmsg)
341 fprintf(stderr, a->notvolmsg, a->volname);
342 goto done;
343 }
344#ifdef HAVE_VOLUME_MANAGER
345 if (getdev.data_subvol_dev && dname) {
346 fprintf(stderr, "%s: "
347 "%s has a data subvolume, cannot specify %s\n",
348 progname, a->volname, dname);
349 goto done;
350 }
351 if (getdev.log_subvol_dev && logname) {
352 fprintf(stderr, "%s: "
353 "%s has a log subvolume, cannot specify %s\n",
354 progname, a->volname, logname);
355 goto done;
356 }
357 if (getdev.rt_subvol_dev && rtname) {
358 fprintf(stderr, "%s: %s has a realtime subvolume, "
359 "cannot specify %s\n",
360 progname, a->volname, rtname);
361 goto done;
362 }
363 if (!dname && getdev.data_subvol_dev) {
364 strcpy(dpath, "/tmp/libxfsdXXXXXX");
365 (void)mktemp(dpath);
366 if (mknod(dpath, S_IFCHR | 0600,
367 getdev.data_subvol_dev) < 0) {
368 fprintf(stderr, "%s: mknod failed: %s\n",
369 progname, strerror(errno));
370 goto done;
371 }
372 dname = dpath;
373 }
374 if (!logname && getdev.log_subvol_dev) {
375 strcpy(logpath, "/tmp/libxfslXXXXXX");
376 (void)mktemp(logpath);
377 if (mknod(logpath, S_IFCHR | 0600,
378 getdev.log_subvol_dev) < 0) {
379 fprintf(stderr, "%s: mknod failed: %s\n",
380 progname, strerror(errno));
381 goto done;
382 }
383 logname = logpath;
384 }
385 if (!rtname && getdev.rt_subvol_dev) {
386 strcpy(rtpath, "/tmp/libxfsrXXXXXX");
387 (void)mktemp(rtpath);
388 if (mknod(rtpath, S_IFCHR | 0600,
389 getdev.rt_subvol_dev) < 0) {
390 fprintf(stderr, "%s: mknod failed: %s\n",
391 progname, strerror(errno));
392 goto done;
393 }
394 rtname = rtpath;
395 }
396#endif
397 }
398voldone:
399 if (dname) {
400 if (dname[0] != '/' && needcd)
401 chdir(curdir);
402 if (a->disfile) {
403 a->ddev= libxfs_device_open(dname, a->dcreat, readonly);
404 a->dfd = libxfs_device_to_fd(a->ddev);
405 } else {
406 if (stat64(dname, &stbuf) < 0) {
407 fprintf(stderr, "%s: stat64 failed on %s: %s\n",
408 progname, dname, strerror(errno));
409 goto done;
410 }
411 if (!(rawfile = findrawpath(dname))) {
412 fprintf(stderr, "%s: can't find a char device "
413 "matching %s\n", progname, dname);
414 goto done;
415 }
416 if (!(blockfile = findblockpath(dname))) {
417 fprintf(stderr, "%s: can't find a block device "
418 "matching %s\n", progname, dname);
419 goto done;
420 }
421 if (!readonly && !inactive && check_ismounted(
422 dname, blockfile, 1))
423 goto done;
424 if (inactive && check_isactive(
425 dname, blockfile, readonly))
426 goto done;
427 a->ddev = libxfs_device_open(rawfile,
428 a->dcreat, readonly);
429 a->dfd = libxfs_device_to_fd(a->ddev);
430 a->dsize = findsize(rawfile);
431 }
432 needcd = 1;
433 } else
434 a->dsize = 0;
435 if (logname) {
436 if (logname[0] != '/' && needcd)
437 chdir(curdir);
438 if (a->lisfile) {
439 a->logdev = libxfs_device_open(logname,
440 a->lcreat, readonly);
441 a->logfd = libxfs_device_to_fd(a->logdev);
442 } else {
443 if (stat64(logname, &stbuf) < 0) {
444 fprintf(stderr, "%s: stat64 failed on %s: %s\n",
445 progname, logname, strerror(errno));
446 goto done;
447 }
448 if (!(rawfile = findrawpath(logname))) {
449 fprintf(stderr, "%s: can't find a char device "
450 "matching %s\n", progname, logname);
451 goto done;
452 }
453 if (!(blockfile = findblockpath(logname))) {
454 fprintf(stderr, "%s: can't find a block device "
455 "matching %s\n", progname, logname);
456 goto done;
457 }
458 if (!readonly && !inactive && check_ismounted(
459 logname, blockfile, 1))
460 goto done;
461 else if (inactive && check_isactive(
462 logname, blockfile, readonly))
463 goto done;
464 a->logdev = libxfs_device_open(rawfile,
465 a->lcreat, readonly);
466 a->logfd = libxfs_device_to_fd(a->logdev);
467 a->logBBsize = findsize(rawfile);
468 }
469 needcd = 1;
470 } else
471 a->logBBsize = 0;
472 if (rtname) {
473 if (rtname[0] != '/' && needcd)
474 chdir(curdir);
475 if (a->risfile) {
476 a->rtdev = libxfs_device_open(rtname,
477 a->rcreat, readonly);
478 a->rtfd = libxfs_device_to_fd(a->rtdev);
479 } else {
480 if (stat64(rtname, &stbuf) < 0) {
481 fprintf(stderr, "%s: stat64 failed on %s: %s\n",
482 progname, rtname, strerror(errno));
483 goto done;
484 }
485 if (!(rawfile = findrawpath(rtname))) {
486 fprintf(stderr, "%s: can't find a char device "
487 "matching %s\n", progname, rtname);
488 goto done;
489 }
490 if (!(blockfile = findblockpath(rtname))) {
491 fprintf(stderr, "%s: can't find a block device "
492 "matching %s\n", progname, rtname);
493 goto done;
494 }
495 if (!readonly && !inactive && check_ismounted(
496 rtname, blockfile, 1))
497 goto done;
498 if (inactive && check_isactive(
499 rtname, blockfile, readonly))
500 goto done;
501 a->rtdev = libxfs_device_open(rawfile,
502 a->rcreat, readonly);
503 a->rtfd = libxfs_device_to_fd(a->rtdev);
504 a->rtsize = findsize(rawfile);
505 }
506 needcd = 1;
507 } else
508 a->rtsize = 0;
509 if (a->dsize < 0) {
510 fprintf(stderr, "%s: can't get size for data subvolume\n",
511 progname);
512 goto done;
513 }
514 if (a->logBBsize < 0) {
515 fprintf(stderr, "%s: can't get size for log subvolume\n",
516 progname);
517 goto done;
518 }
519 if (a->rtsize < 0) {
520 fprintf(stderr, "%s: can't get size for realtime subvolume\n",
521 progname);
522 goto done;
523 }
524 if (needcd)
525 chdir(curdir);
526 rval = 1;
527done:
528 if (dpath[0])
529 unlink(dpath);
530 if (logpath[0])
531 unlink(logpath);
532 if (rtpath[0])
533 unlink(rtpath);
534 if (fd >= 0)
535 close(fd);
536 if (!rval && a->ddev)
537 libxfs_device_close(a->ddev);
538 if (!rval && a->logdev)
539 libxfs_device_close(a->logdev);
540 if (!rval && a->rtdev)
541 libxfs_device_close(a->rtdev);
542 return rval;
543}
544
545
546/*
547 * Initialize/destroy all of the zone allocators we use.
548 */
549static void
550manage_zones(int release)
551{
552 extern xfs_zone_t *xfs_ili_zone;
553 extern xfs_zone_t *xfs_inode_zone;
554 extern xfs_zone_t *xfs_ifork_zone;
555 extern xfs_zone_t *xfs_dabuf_zone;
556 extern xfs_zone_t *xfs_buf_item_zone;
557 extern xfs_zone_t *xfs_da_state_zone;
558 extern xfs_zone_t *xfs_btree_cur_zone;
559 extern xfs_zone_t *xfs_bmap_free_item_zone;
560 extern void xfs_dir_startup();
561
562 if (release) { /* free zone allocation */
563 libxfs_free(xfs_inode_zone);
564 libxfs_free(xfs_ifork_zone);
565 libxfs_free(xfs_dabuf_zone);
566 libxfs_free(xfs_buf_item_zone);
567 libxfs_free(xfs_da_state_zone);
568 libxfs_free(xfs_btree_cur_zone);
569 libxfs_free(xfs_bmap_free_item_zone);
570 return;
571 }
572 /* otherwise initialise zone allocation */
573 xfs_inode_zone = libxfs_zone_init(sizeof(xfs_inode_t), "xfs_inode");
574 xfs_ifork_zone = libxfs_zone_init(sizeof(xfs_ifork_t), "xfs_ifork");
575 xfs_dabuf_zone = libxfs_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf");
576 xfs_ili_zone = libxfs_zone_init(
577 sizeof(xfs_inode_log_item_t), "xfs_inode_log_item");
578 xfs_buf_item_zone = libxfs_zone_init(
579 sizeof(xfs_buf_log_item_t), "xfs_buf_log_item");
580 xfs_da_state_zone = libxfs_zone_init(
581 sizeof(xfs_da_state_t), "xfs_da_state");
582 xfs_btree_cur_zone = libxfs_zone_init(
583 sizeof(xfs_btree_cur_t), "xfs_btree_cur");
584 xfs_bmap_free_item_zone = libxfs_zone_init(
585 sizeof(xfs_bmap_free_item_t), "xfs_bmap_free_item");
586 xfs_dir_startup();
587}
588
589/*
590 * Get the bitmap and summary inodes into the mount structure
591 * at mount time.
592 */
593static int
594rtmount_inodes(xfs_mount_t *mp)
595{
596 int error;
597 xfs_sb_t *sbp;
598
599 sbp = &mp->m_sb;
600 if (sbp->sb_rbmino == NULLFSINO)
601 return 0;
602 error = libxfs_iread(mp, NULL, sbp->sb_rbmino, &mp->m_rbmip, 0);
603 if (error) {
604 fprintf(stderr, "%s: cannot read realtime bitmap inode (%d)\n",
605 progname, error);
606 return error;
607 }
608 ASSERT(mp->m_rbmip != NULL);
609 ASSERT(sbp->sb_rsumino != NULLFSINO);
610 error = libxfs_iread(mp, NULL, sbp->sb_rsumino, &mp->m_rsumip, 0);
611 if (error) {
612 fprintf(stderr, "%s: cannot read realtime summary inode (%d)\n",
613 progname, error);
614 return error;
615 }
616 ASSERT(mp->m_rsumip != NULL);
617 return 0;
618}
619
620/*
621 * Mount structure initialization, provides a filled-in xfs_mount_t
622 * such that the numerous XFS_* macros can be used. If dev is zero,
623 * no IO will be performed (no size checks, read root inodes).
624 */
625xfs_mount_t *
626libxfs_mount(
627 xfs_mount_t *mp,
628 xfs_sb_t *sb,
629 dev_t dev,
630 dev_t logdev,
631 dev_t rtdev,
632 int rrootinos)
633{
634 xfs_daddr_t d;
635 xfs_buf_t *bp;
636 xfs_sb_t *sbp;
637 size_t size;
638 int error;
639
640 mp->m_dev = dev;
641 mp->m_rtdev = rtdev;
642 mp->m_logdev = logdev;
643 mp->m_sb = *sb;
644 sbp = &(mp->m_sb);
645 manage_zones(0);
646
647 libxfs_mount_common(mp, sb);
648
649 libxfs_alloc_compute_maxlevels(mp);
650 libxfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
651 libxfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
652 libxfs_ialloc_compute_maxlevels(mp);
653
654 if (sbp->sb_imax_pct) {
655 /* Make sure the maximum inode count is a multiple of the
656 * units we allocate inodes in.
657 */
658 mp->m_maxicount = (sbp->sb_dblocks * sbp->sb_imax_pct) / 100;
659 mp->m_maxicount = ((mp->m_maxicount / mp->m_ialloc_blks) *
660 mp->m_ialloc_blks) << sbp->sb_inopblog;
661 } else
662 mp->m_maxicount = 0;
663
664 mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
665
666 /*
667 * Set whether we're using inode alignment.
668 */
669 if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) &&
670 mp->m_sb.sb_inoalignmt >=
671 XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
672 mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
673 else
674 mp->m_inoalign_mask = 0;
675 /*
676 * If we are using stripe alignment, check whether
677 * the stripe unit is a multiple of the inode alignment
678 */
679 if ( mp->m_dalign
680 && mp->m_inoalign_mask && !(mp->m_dalign & mp->m_inoalign_mask))
681 mp->m_sinoalign = mp->m_dalign;
682 else
683 mp->m_sinoalign = 0;
684
685 /*
686 * Check that the data (and log if separate) are an ok size.
687 */
688 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
689 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
690 fprintf(stderr, "%s: size check failed\n", progname);
691 return NULL;
692 }
693
694 /* Initialize the appropriate directory manager */
695 if (XFS_SB_VERSION_HASDIRV2(sbp))
696 libxfs_dir2_mount(mp);
697 else
698 libxfs_dir_mount(mp);
699
700 /* Initialize the precomputed transaction reservations values */
701 libxfs_trans_init(mp);
702
703 if (dev == 0) /* maxtrres, we have no device so leave now */
704 return mp;
705
706 bp = libxfs_readbuf(mp->m_dev, d - 1, 1, 0);
707 if (bp == NULL) {
708 fprintf(stderr, "%s: data size check failed\n", progname);
709 return NULL;
710 }
711 libxfs_putbuf(bp);
712
713 if (mp->m_logdev && mp->m_logdev != mp->m_dev) {
714 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
715 if ( (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) ||
716 (!(bp = libxfs_readbuf(mp->m_logdev, d - 1, 1, 1)))) {
717 fprintf(stderr, "%s: log size checks failed\n",
718 progname);
719 return NULL;
720 }
721 libxfs_putbuf(bp);
722 }
723
724 /* Initialize realtime fields in the mount structure */
725 if (libxfs_rtmount_init(mp)) {
726 fprintf(stderr, "%s: real-time device init failed\n", progname);
727 return NULL;
728 }
729
730 /* Allocate and initialize the per-ag data */
731 size = sbp->sb_agcount * sizeof(xfs_perag_t);
732 if ((mp->m_perag = calloc(size, 1)) == NULL) {
733 fprintf(stderr, "%s: failed to alloc %d bytes: %s\n",
734 progname, size, strerror(errno));
735 exit(1);
736 }
737
738 /*
739 * mkfs calls mount before the root inode is allocated.
740 */
741 if (rrootinos && sbp->sb_rootino != NULLFSINO) {
742 error = libxfs_iread(mp, NULL, sbp->sb_rootino,
743 &mp->m_rootip, 0);
744 if (error) {
745 fprintf(stderr, "%s: cannot read root inode (%d)\n",
746 progname, error);
747 return NULL;
748 }
749 ASSERT(mp->m_rootip != NULL);
750 }
751 if (rrootinos && rtmount_inodes(mp))
752 return NULL;
753 return mp;
754}
755
756/*
757 * Release any resourse obtained during a mount.
758 */
759void
760libxfs_umount(xfs_mount_t *mp)
761{
762 manage_zones(1);
763 free(mp->m_perag);
764}