]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - mkfs/proto.c
xfsprogs: Release v6.7.0
[thirdparty/xfsprogs-dev.git] / mkfs / proto.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6
7 #include "libxfs.h"
8 #include <sys/stat.h>
9 #include "xfs_multidisk.h"
10
11 /*
12 * Prototypes for internal functions.
13 */
14 static char *getstr(char **pp);
15 static void fail(char *msg, int i);
16 static struct xfs_trans * getres(struct xfs_mount *mp, uint blocks);
17 static void rsvfile(xfs_mount_t *mp, xfs_inode_t *ip, long long len);
18 static int newfile(xfs_trans_t *tp, xfs_inode_t *ip, int symlink, int logit,
19 char *buf, int len);
20 static char *newregfile(char **pp, int *len);
21 static void rtinit(xfs_mount_t *mp);
22 static long filesize(int fd);
23
24 /*
25 * Use this for block reservations needed for mkfs's conditions
26 * (basically no fragmentation).
27 */
28 #define MKFS_BLOCKRES_INODE \
29 ((uint)(mp->m_ialloc_blks + (mp->m_in_maxlevels - 1)))
30 #define MKFS_BLOCKRES(rb) \
31 ((uint)(MKFS_BLOCKRES_INODE + XFS_DA_NODE_MAXDEPTH + \
32 (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1) + (rb)))
33
34 static long long
35 getnum(
36 const char *str,
37 unsigned int blksize,
38 unsigned int sectsize,
39 bool convert)
40 {
41 long long i;
42 char *sp;
43
44 if (convert)
45 return cvtnum(blksize, sectsize, str);
46
47 i = strtoll(str, &sp, 0);
48 if (i == 0 && sp == str)
49 return -1LL;
50 if (*sp != '\0')
51 return -1LL; /* trailing garbage */
52 return i;
53 }
54
55 char *
56 setup_proto(
57 char *fname)
58 {
59 char *buf = NULL;
60 static char dflt[] = "d--755 0 0 $";
61 int fd;
62 long size;
63
64 if (!fname)
65 return dflt;
66 if ((fd = open(fname, O_RDONLY)) < 0 || (size = filesize(fd)) < 0) {
67 fprintf(stderr, _("%s: failed to open %s: %s\n"),
68 progname, fname, strerror(errno));
69 goto out_fail;
70 }
71
72 buf = malloc(size + 1);
73 if (read(fd, buf, size) < size) {
74 fprintf(stderr, _("%s: read failed on %s: %s\n"),
75 progname, fname, strerror(errno));
76 goto out_fail;
77 }
78 if (buf[size - 1] != '\n') {
79 fprintf(stderr, _("%s: proto file %s premature EOF\n"),
80 progname, fname);
81 goto out_fail;
82 }
83 buf[size] = '\0';
84 /*
85 * Skip past the stuff there for compatibility, a string and 2 numbers.
86 */
87 (void)getstr(&buf); /* boot image name */
88 (void)getnum(getstr(&buf), 0, 0, false); /* block count */
89 (void)getnum(getstr(&buf), 0, 0, false); /* inode count */
90 close(fd);
91 return buf;
92
93 out_fail:
94 if (fd >= 0)
95 close(fd);
96 free(buf);
97 exit(1);
98 }
99
100 static void
101 fail(
102 char *msg,
103 int i)
104 {
105 fprintf(stderr, "%s: %s [%d - %s]\n", progname, msg, i, strerror(i));
106 exit(1);
107 }
108
109 void
110 res_failed(
111 int i)
112 {
113 fail(_("cannot reserve space"), i);
114 }
115
116 static struct xfs_trans *
117 getres(
118 struct xfs_mount *mp,
119 uint blocks)
120 {
121 struct xfs_trans *tp;
122 int i;
123 uint r;
124
125 for (i = 0, r = MKFS_BLOCKRES(blocks); r >= blocks; r--) {
126 i = -libxfs_trans_alloc_rollable(mp, r, &tp);
127 if (i == 0)
128 return tp;
129 }
130 res_failed(i);
131 /* NOTREACHED */
132 return NULL;
133 }
134
135 static char *
136 getstr(
137 char **pp)
138 {
139 char c;
140 char *p;
141 char *rval;
142
143 p = *pp;
144 while ((c = *p)) {
145 switch (c) {
146 case ' ':
147 case '\t':
148 case '\n':
149 p++;
150 continue;
151 case ':':
152 p++;
153 while (*p++ != '\n')
154 ;
155 continue;
156 default:
157 rval = p;
158 while (c != ' ' && c != '\t' && c != '\n' && c != '\0')
159 c = *++p;
160 *p++ = '\0';
161 *pp = p;
162 return rval;
163 }
164 }
165 if (c != '\0') {
166 fprintf(stderr, _("%s: premature EOF in prototype file\n"),
167 progname);
168 exit(1);
169 }
170 return NULL;
171 }
172
173 static void
174 rsvfile(
175 xfs_mount_t *mp,
176 xfs_inode_t *ip,
177 long long llen)
178 {
179 int error;
180 xfs_trans_t *tp;
181
182 error = -libxfs_alloc_file_space(ip, 0, llen, 1, 0);
183
184 if (error) {
185 fail(_("error reserving space for a file"), error);
186 exit(1);
187 }
188
189 /*
190 * update the inode timestamp, mode, and prealloc flag bits
191 */
192 error = -libxfs_trans_alloc_rollable(mp, 0, &tp);
193 if (error)
194 fail(_("allocating transaction for a file"), error);
195 libxfs_trans_ijoin(tp, ip, 0);
196
197 VFS_I(ip)->i_mode &= ~S_ISUID;
198
199 /*
200 * Note that we don't have to worry about mandatory
201 * file locking being disabled here because we only
202 * clear the S_ISGID bit if the Group execute bit is
203 * on, but if it was on then mandatory locking wouldn't
204 * have been enabled.
205 */
206 if (VFS_I(ip)->i_mode & S_IXGRP)
207 VFS_I(ip)->i_mode &= ~S_ISGID;
208
209 libxfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
210
211 ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
212
213 libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
214 error = -libxfs_trans_commit(tp);
215 if (error)
216 fail(_("committing space for a file failed"), error);
217 }
218
219 static int
220 newfile(
221 xfs_trans_t *tp,
222 xfs_inode_t *ip,
223 int symlink,
224 int logit,
225 char *buf,
226 int len)
227 {
228 xfs_buf_t *bp;
229 xfs_daddr_t d;
230 int error;
231 int flags;
232 xfs_bmbt_irec_t map;
233 xfs_mount_t *mp;
234 xfs_extlen_t nb;
235 int nmap;
236
237 flags = 0;
238 mp = ip->i_mount;
239 if (symlink && len <= XFS_IFORK_DSIZE(ip)) {
240 libxfs_init_local_fork(ip, XFS_DATA_FORK, buf, len);
241 ip->i_d.di_format = XFS_DINODE_FMT_LOCAL;
242 flags = XFS_ILOG_DDATA;
243 } else if (len > 0) {
244 nb = XFS_B_TO_FSB(mp, len);
245 nmap = 1;
246 error = -libxfs_bmapi_write(tp, ip, 0, nb, 0, nb, &map, &nmap);
247 if (error) {
248 fail(_("error allocating space for a file"), error);
249 }
250 if (nmap != 1) {
251 fprintf(stderr,
252 _("%s: cannot allocate space for file\n"),
253 progname);
254 exit(1);
255 }
256 d = XFS_FSB_TO_DADDR(mp, map.br_startblock);
257 bp = libxfs_trans_get_buf(logit ? tp : NULL, mp->m_dev, d,
258 nb << mp->m_blkbb_log, 0);
259 memmove(bp->b_addr, buf, len);
260 if (len < bp->b_bcount)
261 memset((char *)bp->b_addr + len, 0, bp->b_bcount - len);
262 if (logit)
263 libxfs_trans_log_buf(tp, bp, 0, bp->b_bcount - 1);
264 else
265 libxfs_writebuf(bp, LIBXFS_EXIT_ON_FAILURE);
266 }
267 ip->i_d.di_size = len;
268 return flags;
269 }
270
271 static char *
272 newregfile(
273 char **pp,
274 int *len)
275 {
276 char *buf;
277 int fd;
278 char *fname;
279 long size;
280
281 fname = getstr(pp);
282 if ((fd = open(fname, O_RDONLY)) < 0 || (size = filesize(fd)) < 0) {
283 fprintf(stderr, _("%s: cannot open %s: %s\n"),
284 progname, fname, strerror(errno));
285 exit(1);
286 }
287 if ((*len = (int)size)) {
288 buf = malloc(size);
289 if (read(fd, buf, size) < size) {
290 fprintf(stderr, _("%s: read failed on %s: %s\n"),
291 progname, fname, strerror(errno));
292 exit(1);
293 }
294 } else
295 buf = NULL;
296 close(fd);
297 return buf;
298 }
299
300 static void
301 newdirent(
302 xfs_mount_t *mp,
303 xfs_trans_t *tp,
304 xfs_inode_t *pip,
305 struct xfs_name *name,
306 xfs_ino_t inum)
307 {
308 int error;
309 int rsv;
310
311 rsv = XFS_DIRENTER_SPACE_RES(mp, name->len);
312
313 error = -libxfs_dir_createname(tp, pip, name, inum, rsv);
314 if (error)
315 fail(_("directory createname error"), error);
316 }
317
318 static void
319 newdirectory(
320 xfs_mount_t *mp,
321 xfs_trans_t *tp,
322 xfs_inode_t *dp,
323 xfs_inode_t *pdp)
324 {
325 int error;
326
327 error = -libxfs_dir_init(tp, dp, pdp);
328 if (error)
329 fail(_("directory create error"), error);
330 }
331
332 static void
333 parseproto(
334 xfs_mount_t *mp,
335 xfs_inode_t *pip,
336 struct fsxattr *fsxp,
337 char **pp,
338 char *name)
339 {
340 #define IF_REGULAR 0
341 #define IF_RESERVED 1
342 #define IF_BLOCK 2
343 #define IF_CHAR 3
344 #define IF_DIRECTORY 4
345 #define IF_SYMLINK 5
346 #define IF_FIFO 6
347
348 char *buf;
349 int error;
350 int flags;
351 int fmt;
352 int i;
353 xfs_inode_t *ip;
354 int len;
355 long long llen;
356 int majdev;
357 int mindev;
358 int mode;
359 char *mstr;
360 xfs_trans_t *tp;
361 int val;
362 int isroot = 0;
363 cred_t creds;
364 char *value;
365 struct xfs_name xname;
366
367 memset(&creds, 0, sizeof(creds));
368 mstr = getstr(pp);
369 switch (mstr[0]) {
370 case '-':
371 fmt = IF_REGULAR;
372 break;
373 case 'r':
374 fmt = IF_RESERVED;
375 break;
376 case 'b':
377 fmt = IF_BLOCK;
378 break;
379 case 'c':
380 fmt = IF_CHAR;
381 break;
382 case 'd':
383 fmt = IF_DIRECTORY;
384 break;
385 case 'l':
386 fmt = IF_SYMLINK;
387 break;
388 case 'p':
389 fmt = IF_FIFO;
390 break;
391 default:
392 fprintf(stderr, _("%s: bad format string %s\n"),
393 progname, mstr);
394 exit(1);
395 }
396 mode = 0;
397 switch (mstr[1]) {
398 case '-':
399 break;
400 case 'u':
401 mode |= S_ISUID;
402 break;
403 default:
404 fprintf(stderr, _("%s: bad format string %s\n"),
405 progname, mstr);
406 exit(1);
407 }
408 switch (mstr[2]) {
409 case '-':
410 break;
411 case 'g':
412 mode |= S_ISGID;
413 break;
414 default:
415 fprintf(stderr, _("%s: bad format string %s\n"),
416 progname, mstr);
417 exit(1);
418 }
419 val = 0;
420 for (i = 3; i < 6; i++) {
421 if (mstr[i] < '0' || mstr[i] > '7') {
422 fprintf(stderr, _("%s: bad format string %s\n"),
423 progname, mstr);
424 exit(1);
425 }
426 val = val * 8 + mstr[i] - '0';
427 }
428 mode |= val;
429 creds.cr_uid = (int)getnum(getstr(pp), 0, 0, false);
430 creds.cr_gid = (int)getnum(getstr(pp), 0, 0, false);
431 xname.name = (unsigned char *)name;
432 xname.len = name ? strlen(name) : 0;
433 xname.type = 0;
434 flags = XFS_ILOG_CORE;
435 switch (fmt) {
436 case IF_REGULAR:
437 buf = newregfile(pp, &len);
438 tp = getres(mp, XFS_B_TO_FSB(mp, len));
439 error = -libxfs_inode_alloc(&tp, pip, mode|S_IFREG, 1, 0,
440 &creds, fsxp, &ip);
441 if (error)
442 fail(_("Inode allocation failed"), error);
443 flags |= newfile(tp, ip, 0, 0, buf, len);
444 if (buf)
445 free(buf);
446 libxfs_trans_ijoin(tp, pip, 0);
447 xname.type = XFS_DIR3_FT_REG_FILE;
448 newdirent(mp, tp, pip, &xname, ip->i_ino);
449 break;
450
451 case IF_RESERVED: /* pre-allocated space only */
452 value = getstr(pp);
453 llen = getnum(value, mp->m_sb.sb_blocksize,
454 mp->m_sb.sb_sectsize, true);
455 if (llen < 0) {
456 fprintf(stderr,
457 _("%s: Bad value %s for proto file %s\n"),
458 progname, value, name);
459 exit(1);
460 }
461 tp = getres(mp, XFS_B_TO_FSB(mp, llen));
462
463 error = -libxfs_inode_alloc(&tp, pip, mode|S_IFREG, 1, 0,
464 &creds, fsxp, &ip);
465 if (error)
466 fail(_("Inode pre-allocation failed"), error);
467
468 libxfs_trans_ijoin(tp, pip, 0);
469
470 xname.type = XFS_DIR3_FT_REG_FILE;
471 newdirent(mp, tp, pip, &xname, ip->i_ino);
472 libxfs_trans_log_inode(tp, ip, flags);
473 error = -libxfs_trans_commit(tp);
474 if (error)
475 fail(_("Space preallocation failed."), error);
476 rsvfile(mp, ip, llen);
477 libxfs_irele(ip);
478 return;
479
480 case IF_BLOCK:
481 tp = getres(mp, 0);
482 majdev = getnum(getstr(pp), 0, 0, false);
483 mindev = getnum(getstr(pp), 0, 0, false);
484 error = -libxfs_inode_alloc(&tp, pip, mode|S_IFBLK, 1,
485 IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip);
486 if (error) {
487 fail(_("Inode allocation failed"), error);
488 }
489 libxfs_trans_ijoin(tp, pip, 0);
490 xname.type = XFS_DIR3_FT_BLKDEV;
491 newdirent(mp, tp, pip, &xname, ip->i_ino);
492 flags |= XFS_ILOG_DEV;
493 break;
494
495 case IF_CHAR:
496 tp = getres(mp, 0);
497 majdev = getnum(getstr(pp), 0, 0, false);
498 mindev = getnum(getstr(pp), 0, 0, false);
499 error = -libxfs_inode_alloc(&tp, pip, mode|S_IFCHR, 1,
500 IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip);
501 if (error)
502 fail(_("Inode allocation failed"), error);
503 libxfs_trans_ijoin(tp, pip, 0);
504 xname.type = XFS_DIR3_FT_CHRDEV;
505 newdirent(mp, tp, pip, &xname, ip->i_ino);
506 flags |= XFS_ILOG_DEV;
507 break;
508
509 case IF_FIFO:
510 tp = getres(mp, 0);
511 error = -libxfs_inode_alloc(&tp, pip, mode|S_IFIFO, 1, 0,
512 &creds, fsxp, &ip);
513 if (error)
514 fail(_("Inode allocation failed"), error);
515 libxfs_trans_ijoin(tp, pip, 0);
516 xname.type = XFS_DIR3_FT_FIFO;
517 newdirent(mp, tp, pip, &xname, ip->i_ino);
518 break;
519 case IF_SYMLINK:
520 buf = getstr(pp);
521 len = (int)strlen(buf);
522 tp = getres(mp, XFS_B_TO_FSB(mp, len));
523 error = -libxfs_inode_alloc(&tp, pip, mode|S_IFLNK, 1, 0,
524 &creds, fsxp, &ip);
525 if (error)
526 fail(_("Inode allocation failed"), error);
527 flags |= newfile(tp, ip, 1, 1, buf, len);
528 libxfs_trans_ijoin(tp, pip, 0);
529 xname.type = XFS_DIR3_FT_SYMLINK;
530 newdirent(mp, tp, pip, &xname, ip->i_ino);
531 break;
532 case IF_DIRECTORY:
533 tp = getres(mp, 0);
534 error = -libxfs_inode_alloc(&tp, pip, mode|S_IFDIR, 1, 0,
535 &creds, fsxp, &ip);
536 if (error)
537 fail(_("Inode allocation failed"), error);
538 inc_nlink(VFS_I(ip)); /* account for . */
539 if (!pip) {
540 pip = ip;
541 mp->m_sb.sb_rootino = ip->i_ino;
542 libxfs_log_sb(tp);
543 isroot = 1;
544 } else {
545 libxfs_trans_ijoin(tp, pip, 0);
546 xname.type = XFS_DIR3_FT_DIR;
547 newdirent(mp, tp, pip, &xname, ip->i_ino);
548 inc_nlink(VFS_I(pip));
549 libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE);
550 }
551 newdirectory(mp, tp, ip, pip);
552 libxfs_trans_log_inode(tp, ip, flags);
553 error = -libxfs_trans_commit(tp);
554 if (error)
555 fail(_("Directory inode allocation failed."), error);
556 /*
557 * RT initialization. Do this here to ensure that
558 * the RT inodes get placed after the root inode.
559 */
560 if (isroot)
561 rtinit(mp);
562 tp = NULL;
563 for (;;) {
564 name = getstr(pp);
565 if (!name)
566 break;
567 if (strcmp(name, "$") == 0)
568 break;
569 parseproto(mp, ip, fsxp, pp, name);
570 }
571 libxfs_irele(ip);
572 return;
573 default:
574 ASSERT(0);
575 fail(_("Unknown format"), EINVAL);
576 }
577 libxfs_trans_log_inode(tp, ip, flags);
578 error = -libxfs_trans_commit(tp);
579 if (error) {
580 fail(_("Error encountered creating file from prototype file"),
581 error);
582 }
583 libxfs_irele(ip);
584 }
585
586 void
587 parse_proto(
588 xfs_mount_t *mp,
589 struct fsxattr *fsx,
590 char **pp)
591 {
592 parseproto(mp, NULL, fsx, pp, NULL);
593 }
594
595 /*
596 * Allocate the realtime bitmap and summary inodes, and fill in data if any.
597 */
598 static void
599 rtinit(
600 xfs_mount_t *mp)
601 {
602 xfs_fileoff_t bno;
603 xfs_fileoff_t ebno;
604 xfs_bmbt_irec_t *ep;
605 int error;
606 int i;
607 xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP];
608 xfs_extlen_t nsumblocks;
609 uint blocks;
610 int nmap;
611 xfs_inode_t *rbmip;
612 xfs_inode_t *rsumip;
613 xfs_trans_t *tp;
614 struct cred creds;
615 struct fsxattr fsxattrs;
616
617 /*
618 * First, allocate the inodes.
619 */
620 i = -libxfs_trans_alloc_rollable(mp, MKFS_BLOCKRES_INODE, &tp);
621 if (i)
622 res_failed(i);
623
624 memset(&creds, 0, sizeof(creds));
625 memset(&fsxattrs, 0, sizeof(fsxattrs));
626 error = -libxfs_inode_alloc(&tp, NULL, S_IFREG, 1, 0,
627 &creds, &fsxattrs, &rbmip);
628 if (error) {
629 fail(_("Realtime bitmap inode allocation failed"), error);
630 }
631 /*
632 * Do our thing with rbmip before allocating rsumip,
633 * because the next call to ialloc() may
634 * commit the transaction in which rbmip was allocated.
635 */
636 mp->m_sb.sb_rbmino = rbmip->i_ino;
637 rbmip->i_d.di_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize;
638 rbmip->i_d.di_flags = XFS_DIFLAG_NEWRTBM;
639 *(uint64_t *)&VFS_I(rbmip)->i_atime = 0;
640 libxfs_trans_log_inode(tp, rbmip, XFS_ILOG_CORE);
641 libxfs_log_sb(tp);
642 mp->m_rbmip = rbmip;
643 error = -libxfs_inode_alloc(&tp, NULL, S_IFREG, 1, 0,
644 &creds, &fsxattrs, &rsumip);
645 if (error) {
646 fail(_("Realtime summary inode allocation failed"), error);
647 }
648 mp->m_sb.sb_rsumino = rsumip->i_ino;
649 rsumip->i_d.di_size = mp->m_rsumsize;
650 libxfs_trans_log_inode(tp, rsumip, XFS_ILOG_CORE);
651 libxfs_log_sb(tp);
652 error = -libxfs_trans_commit(tp);
653 if (error)
654 fail(_("Completion of the realtime summary inode failed"),
655 error);
656 mp->m_rsumip = rsumip;
657 /*
658 * Next, give the bitmap file some zero-filled blocks.
659 */
660 blocks = mp->m_sb.sb_rbmblocks +
661 XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1;
662 i = -libxfs_trans_alloc_rollable(mp, blocks, &tp);
663 if (i)
664 res_failed(i);
665
666 libxfs_trans_ijoin(tp, rbmip, 0);
667 bno = 0;
668 while (bno < mp->m_sb.sb_rbmblocks) {
669 nmap = XFS_BMAP_MAX_NMAP;
670 error = -libxfs_bmapi_write(tp, rbmip, bno,
671 (xfs_extlen_t)(mp->m_sb.sb_rbmblocks - bno),
672 0, mp->m_sb.sb_rbmblocks, map, &nmap);
673 if (error) {
674 fail(_("Allocation of the realtime bitmap failed"),
675 error);
676 }
677 for (i = 0, ep = map; i < nmap; i++, ep++) {
678 libxfs_device_zero(mp->m_ddev_targp,
679 XFS_FSB_TO_DADDR(mp, ep->br_startblock),
680 XFS_FSB_TO_BB(mp, ep->br_blockcount));
681 bno += ep->br_blockcount;
682 }
683 }
684
685 error = -libxfs_trans_commit(tp);
686 if (error)
687 fail(_("Block allocation of the realtime bitmap inode failed"),
688 error);
689
690 /*
691 * Give the summary file some zero-filled blocks.
692 */
693 nsumblocks = mp->m_rsumsize >> mp->m_sb.sb_blocklog;
694 blocks = nsumblocks + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1;
695 i = -libxfs_trans_alloc_rollable(mp, blocks, &tp);
696 if (i)
697 res_failed(i);
698 libxfs_trans_ijoin(tp, rsumip, 0);
699 bno = 0;
700 while (bno < nsumblocks) {
701 nmap = XFS_BMAP_MAX_NMAP;
702 error = -libxfs_bmapi_write(tp, rsumip, bno,
703 (xfs_extlen_t)(nsumblocks - bno),
704 0, nsumblocks, map, &nmap);
705 if (error) {
706 fail(_("Allocation of the realtime summary failed"),
707 error);
708 }
709 for (i = 0, ep = map; i < nmap; i++, ep++) {
710 libxfs_device_zero(mp->m_ddev_targp,
711 XFS_FSB_TO_DADDR(mp, ep->br_startblock),
712 XFS_FSB_TO_BB(mp, ep->br_blockcount));
713 bno += ep->br_blockcount;
714 }
715 }
716 error = -libxfs_trans_commit(tp);
717 if (error)
718 fail(_("Block allocation of the realtime summary inode failed"),
719 error);
720
721 /*
722 * Free the whole area using transactions.
723 * Do one transaction per bitmap block.
724 */
725 for (bno = 0; bno < mp->m_sb.sb_rextents; bno = ebno) {
726 i = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
727 0, 0, 0, &tp);
728 if (i)
729 res_failed(i);
730 libxfs_trans_ijoin(tp, rbmip, 0);
731 ebno = XFS_RTMIN(mp->m_sb.sb_rextents,
732 bno + NBBY * mp->m_sb.sb_blocksize);
733 error = -libxfs_rtfree_extent(tp, bno, (xfs_extlen_t)(ebno-bno));
734 if (error) {
735 fail(_("Error initializing the realtime space"),
736 error);
737 }
738 error = -libxfs_trans_commit(tp);
739 if (error)
740 fail(_("Initialization of the realtime space failed"),
741 error);
742 }
743 }
744
745 static long
746 filesize(
747 int fd)
748 {
749 struct stat stb;
750
751 if (fstat(fd, &stb) < 0)
752 return -1;
753 return (long)stb.st_size;
754 }