]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxfs/init.c
Bumped ioctl numbers for BLKBSZSET and BLKBSZGET to avoid conflicts with
[thirdparty/xfsprogs-dev.git] / libxfs / init.c
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 BLKBSZSET
45 #define BLKBSZSET _IO(0x12,110) /* set device block size */
46 #endif
47
48 #define findrawpath(x) x
49 #define findblockpath(x) x
50
51 char *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 */
57 int nextfakedev = -1; /* device number to give to next fake device */
58 static struct dev_to_fd {
59 dev_t dev;
60 int fd;
61 } dev_map[MAX_DEVS]={{0}};
62
63 static int
64 check_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 */
91 static int
92 check_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
120 static __int64_t
121 findsize(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 */
163 int
164 libxfs_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 */
180 dev_t
181 libxfs_device_open(char *path, int creat, int readonly, int setblksize)
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 (!readonly && setblksize && (statb.st_mode & S_IFMT) == S_IFBLK) {
206 if (ioctl(fd, BLKBSZSET, &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
238 void
239 libxfs_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 */
268 int
269 libxfs_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 }
398 voldone:
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->setblksize);
405 a->dfd = libxfs_device_to_fd(a->ddev);
406 } else {
407 if (stat64(dname, &stbuf) < 0) {
408 fprintf(stderr, "%s: stat64 failed on %s: %s\n",
409 progname, dname, strerror(errno));
410 goto done;
411 }
412 if (!(rawfile = findrawpath(dname))) {
413 fprintf(stderr, "%s: can't find a char device "
414 "matching %s\n", progname, dname);
415 goto done;
416 }
417 if (!(blockfile = findblockpath(dname))) {
418 fprintf(stderr, "%s: can't find a block device "
419 "matching %s\n", progname, dname);
420 goto done;
421 }
422 if (!readonly && !inactive && check_ismounted(
423 dname, blockfile, 1))
424 goto done;
425 if (inactive && check_isactive(
426 dname, blockfile, readonly))
427 goto done;
428 a->ddev = libxfs_device_open(rawfile,
429 a->dcreat, readonly, a->setblksize);
430 a->dfd = libxfs_device_to_fd(a->ddev);
431 a->dsize = findsize(rawfile);
432 }
433 needcd = 1;
434 } else
435 a->dsize = 0;
436 if (logname) {
437 if (logname[0] != '/' && needcd)
438 chdir(curdir);
439 if (a->lisfile) {
440 a->logdev = libxfs_device_open(logname,
441 a->lcreat, readonly, a->setblksize);
442 a->logfd = libxfs_device_to_fd(a->logdev);
443 } else {
444 if (stat64(logname, &stbuf) < 0) {
445 fprintf(stderr, "%s: stat64 failed on %s: %s\n",
446 progname, logname, strerror(errno));
447 goto done;
448 }
449 if (!(rawfile = findrawpath(logname))) {
450 fprintf(stderr, "%s: can't find a char device "
451 "matching %s\n", progname, logname);
452 goto done;
453 }
454 if (!(blockfile = findblockpath(logname))) {
455 fprintf(stderr, "%s: can't find a block device "
456 "matching %s\n", progname, logname);
457 goto done;
458 }
459 if (!readonly && !inactive && check_ismounted(
460 logname, blockfile, 1))
461 goto done;
462 else if (inactive && check_isactive(
463 logname, blockfile, readonly))
464 goto done;
465 a->logdev = libxfs_device_open(rawfile,
466 a->lcreat, readonly, a->setblksize);
467 a->logfd = libxfs_device_to_fd(a->logdev);
468 a->logBBsize = findsize(rawfile);
469 }
470 needcd = 1;
471 } else
472 a->logBBsize = 0;
473 if (rtname) {
474 if (rtname[0] != '/' && needcd)
475 chdir(curdir);
476 if (a->risfile) {
477 a->rtdev = libxfs_device_open(rtname,
478 a->rcreat, readonly, a->setblksize);
479 a->rtfd = libxfs_device_to_fd(a->rtdev);
480 } else {
481 if (stat64(rtname, &stbuf) < 0) {
482 fprintf(stderr, "%s: stat64 failed on %s: %s\n",
483 progname, rtname, strerror(errno));
484 goto done;
485 }
486 if (!(rawfile = findrawpath(rtname))) {
487 fprintf(stderr, "%s: can't find a char device "
488 "matching %s\n", progname, rtname);
489 goto done;
490 }
491 if (!(blockfile = findblockpath(rtname))) {
492 fprintf(stderr, "%s: can't find a block device "
493 "matching %s\n", progname, rtname);
494 goto done;
495 }
496 if (!readonly && !inactive && check_ismounted(
497 rtname, blockfile, 1))
498 goto done;
499 if (inactive && check_isactive(
500 rtname, blockfile, readonly))
501 goto done;
502 a->rtdev = libxfs_device_open(rawfile,
503 a->rcreat, readonly, a->setblksize);
504 a->rtfd = libxfs_device_to_fd(a->rtdev);
505 a->rtsize = findsize(rawfile);
506 }
507 needcd = 1;
508 } else
509 a->rtsize = 0;
510 if (a->dsize < 0) {
511 fprintf(stderr, "%s: can't get size for data subvolume\n",
512 progname);
513 goto done;
514 }
515 if (a->logBBsize < 0) {
516 fprintf(stderr, "%s: can't get size for log subvolume\n",
517 progname);
518 goto done;
519 }
520 if (a->rtsize < 0) {
521 fprintf(stderr, "%s: can't get size for realtime subvolume\n",
522 progname);
523 goto done;
524 }
525 if (needcd)
526 chdir(curdir);
527 rval = 1;
528 done:
529 if (dpath[0])
530 unlink(dpath);
531 if (logpath[0])
532 unlink(logpath);
533 if (rtpath[0])
534 unlink(rtpath);
535 if (fd >= 0)
536 close(fd);
537 if (!rval && a->ddev)
538 libxfs_device_close(a->ddev);
539 if (!rval && a->logdev)
540 libxfs_device_close(a->logdev);
541 if (!rval && a->rtdev)
542 libxfs_device_close(a->rtdev);
543 return rval;
544 }
545
546
547 /*
548 * Initialize/destroy all of the zone allocators we use.
549 */
550 static void
551 manage_zones(int release)
552 {
553 extern xfs_zone_t *xfs_ili_zone;
554 extern xfs_zone_t *xfs_inode_zone;
555 extern xfs_zone_t *xfs_ifork_zone;
556 extern xfs_zone_t *xfs_dabuf_zone;
557 extern xfs_zone_t *xfs_buf_item_zone;
558 extern xfs_zone_t *xfs_da_state_zone;
559 extern xfs_zone_t *xfs_btree_cur_zone;
560 extern xfs_zone_t *xfs_bmap_free_item_zone;
561 extern void xfs_dir_startup();
562
563 if (release) { /* free zone allocation */
564 libxfs_free(xfs_inode_zone);
565 libxfs_free(xfs_ifork_zone);
566 libxfs_free(xfs_dabuf_zone);
567 libxfs_free(xfs_buf_item_zone);
568 libxfs_free(xfs_da_state_zone);
569 libxfs_free(xfs_btree_cur_zone);
570 libxfs_free(xfs_bmap_free_item_zone);
571 return;
572 }
573 /* otherwise initialise zone allocation */
574 xfs_inode_zone = libxfs_zone_init(sizeof(xfs_inode_t), "xfs_inode");
575 xfs_ifork_zone = libxfs_zone_init(sizeof(xfs_ifork_t), "xfs_ifork");
576 xfs_dabuf_zone = libxfs_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf");
577 xfs_ili_zone = libxfs_zone_init(
578 sizeof(xfs_inode_log_item_t), "xfs_inode_log_item");
579 xfs_buf_item_zone = libxfs_zone_init(
580 sizeof(xfs_buf_log_item_t), "xfs_buf_log_item");
581 xfs_da_state_zone = libxfs_zone_init(
582 sizeof(xfs_da_state_t), "xfs_da_state");
583 xfs_btree_cur_zone = libxfs_zone_init(
584 sizeof(xfs_btree_cur_t), "xfs_btree_cur");
585 xfs_bmap_free_item_zone = libxfs_zone_init(
586 sizeof(xfs_bmap_free_item_t), "xfs_bmap_free_item");
587 xfs_dir_startup();
588 }
589
590 /*
591 * Get the bitmap and summary inodes into the mount structure
592 * at mount time.
593 */
594 static int
595 rtmount_inodes(xfs_mount_t *mp)
596 {
597 int error;
598 xfs_sb_t *sbp;
599
600 sbp = &mp->m_sb;
601 if (sbp->sb_rbmino == NULLFSINO)
602 return 0;
603 error = libxfs_iread(mp, NULL, sbp->sb_rbmino, &mp->m_rbmip, 0);
604 if (error) {
605 fprintf(stderr, "%s: cannot read realtime bitmap inode (%d)\n",
606 progname, error);
607 return error;
608 }
609 ASSERT(mp->m_rbmip != NULL);
610 ASSERT(sbp->sb_rsumino != NULLFSINO);
611 error = libxfs_iread(mp, NULL, sbp->sb_rsumino, &mp->m_rsumip, 0);
612 if (error) {
613 fprintf(stderr, "%s: cannot read realtime summary inode (%d)\n",
614 progname, error);
615 return error;
616 }
617 ASSERT(mp->m_rsumip != NULL);
618 return 0;
619 }
620
621 /*
622 * Mount structure initialization, provides a filled-in xfs_mount_t
623 * such that the numerous XFS_* macros can be used. If dev is zero,
624 * no IO will be performed (no size checks, read root inodes).
625 */
626 xfs_mount_t *
627 libxfs_mount(
628 xfs_mount_t *mp,
629 xfs_sb_t *sb,
630 dev_t dev,
631 dev_t logdev,
632 dev_t rtdev,
633 int rrootinos)
634 {
635 xfs_daddr_t d;
636 xfs_buf_t *bp;
637 xfs_sb_t *sbp;
638 size_t size;
639 int error;
640
641 mp->m_dev = dev;
642 mp->m_rtdev = rtdev;
643 mp->m_logdev = logdev;
644 mp->m_sb = *sb;
645 sbp = &(mp->m_sb);
646 manage_zones(0);
647
648 libxfs_mount_common(mp, sb);
649
650 libxfs_alloc_compute_maxlevels(mp);
651 libxfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
652 libxfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
653 libxfs_ialloc_compute_maxlevels(mp);
654
655 if (sbp->sb_imax_pct) {
656 /* Make sure the maximum inode count is a multiple of the
657 * units we allocate inodes in.
658 */
659 mp->m_maxicount = (sbp->sb_dblocks * sbp->sb_imax_pct) / 100;
660 mp->m_maxicount = ((mp->m_maxicount / mp->m_ialloc_blks) *
661 mp->m_ialloc_blks) << sbp->sb_inopblog;
662 } else
663 mp->m_maxicount = 0;
664
665 mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
666
667 /*
668 * Set whether we're using inode alignment.
669 */
670 if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) &&
671 mp->m_sb.sb_inoalignmt >=
672 XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
673 mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
674 else
675 mp->m_inoalign_mask = 0;
676 /*
677 * If we are using stripe alignment, check whether
678 * the stripe unit is a multiple of the inode alignment
679 */
680 if ( mp->m_dalign
681 && mp->m_inoalign_mask && !(mp->m_dalign & mp->m_inoalign_mask))
682 mp->m_sinoalign = mp->m_dalign;
683 else
684 mp->m_sinoalign = 0;
685
686 /*
687 * Check that the data (and log if separate) are an ok size.
688 */
689 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
690 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
691 fprintf(stderr, "%s: size check failed\n", progname);
692 return NULL;
693 }
694
695 /* Initialize the appropriate directory manager */
696 if (XFS_SB_VERSION_HASDIRV2(sbp))
697 libxfs_dir2_mount(mp);
698 else
699 libxfs_dir_mount(mp);
700
701 /* Initialize the precomputed transaction reservations values */
702 libxfs_trans_init(mp);
703
704 if (dev == 0) /* maxtrres, we have no device so leave now */
705 return mp;
706
707 bp = libxfs_readbuf(mp->m_dev, d - 1, 1, 0);
708 if (bp == NULL) {
709 fprintf(stderr, "%s: data size check failed\n", progname);
710 return NULL;
711 }
712 libxfs_putbuf(bp);
713
714 if (mp->m_logdev && mp->m_logdev != mp->m_dev) {
715 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
716 if ( (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) ||
717 (!(bp = libxfs_readbuf(mp->m_logdev, d - 1, 1, 1)))) {
718 fprintf(stderr, "%s: log size checks failed\n",
719 progname);
720 return NULL;
721 }
722 libxfs_putbuf(bp);
723 }
724
725 /* Initialize realtime fields in the mount structure */
726 if (libxfs_rtmount_init(mp)) {
727 fprintf(stderr, "%s: real-time device init failed\n", progname);
728 return NULL;
729 }
730
731 /* Allocate and initialize the per-ag data */
732 size = sbp->sb_agcount * sizeof(xfs_perag_t);
733 if ((mp->m_perag = calloc(size, 1)) == NULL) {
734 fprintf(stderr, "%s: failed to alloc %d bytes: %s\n",
735 progname, size, strerror(errno));
736 exit(1);
737 }
738
739 /*
740 * mkfs calls mount before the root inode is allocated.
741 */
742 if (rrootinos && sbp->sb_rootino != NULLFSINO) {
743 error = libxfs_iread(mp, NULL, sbp->sb_rootino,
744 &mp->m_rootip, 0);
745 if (error) {
746 fprintf(stderr, "%s: cannot read root inode (%d)\n",
747 progname, error);
748 return NULL;
749 }
750 ASSERT(mp->m_rootip != NULL);
751 }
752 if (rrootinos && rtmount_inodes(mp))
753 return NULL;
754 return mp;
755 }
756
757 /*
758 * Release any resourse obtained during a mount.
759 */
760 void
761 libxfs_umount(xfs_mount_t *mp)
762 {
763 manage_zones(1);
764 free(mp->m_perag);
765 }