]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxfs/util.c
f3b9895438f9e65bf4b7b030c2dc8a678d7bc4f2
[thirdparty/xfsprogs-dev.git] / libxfs / util.c
1 /*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "libxfs_priv.h"
20 #include "libxfs_io.h"
21 #include "init.h"
22 #include "xfs_fs.h"
23 #include "xfs_shared.h"
24 #include "xfs_format.h"
25 #include "xfs_log_format.h"
26 #include "xfs_trans_resv.h"
27 #include "xfs_mount.h"
28 #include "xfs_inode_buf.h"
29 #include "xfs_inode_fork.h"
30 #include "xfs_inode.h"
31 #include "xfs_trans.h"
32 #include "xfs_bmap.h"
33 #include "xfs_bmap_btree.h"
34 #include "xfs_trans_space.h"
35 #include "xfs_ialloc.h"
36 #include "xfs_alloc.h"
37 #include "xfs_bit.h"
38
39 /*
40 * Calculate the worst case log unit reservation for a given superblock
41 * configuration. Copied and munged from the kernel code, and assumes a
42 * worse case header usage (maximum log buffer sizes)
43 */
44 int
45 xfs_log_calc_unit_res(
46 struct xfs_mount *mp,
47 int unit_bytes)
48 {
49 int iclog_space;
50 int iclog_header_size;
51 int iclog_size;
52 uint num_headers;
53
54 if (xfs_sb_version_haslogv2(&mp->m_sb)) {
55 iclog_size = XLOG_MAX_RECORD_BSIZE;
56 iclog_header_size = BBTOB(iclog_size / XLOG_HEADER_CYCLE_SIZE);
57 } else {
58 iclog_size = XLOG_BIG_RECORD_BSIZE;
59 iclog_header_size = BBSIZE;
60 }
61
62 /*
63 * Permanent reservations have up to 'cnt'-1 active log operations
64 * in the log. A unit in this case is the amount of space for one
65 * of these log operations. Normal reservations have a cnt of 1
66 * and their unit amount is the total amount of space required.
67 *
68 * The following lines of code account for non-transaction data
69 * which occupy space in the on-disk log.
70 *
71 * Normal form of a transaction is:
72 * <oph><trans-hdr><start-oph><reg1-oph><reg1><reg2-oph>...<commit-oph>
73 * and then there are LR hdrs, split-recs and roundoff at end of syncs.
74 *
75 * We need to account for all the leadup data and trailer data
76 * around the transaction data.
77 * And then we need to account for the worst case in terms of using
78 * more space.
79 * The worst case will happen if:
80 * - the placement of the transaction happens to be such that the
81 * roundoff is at its maximum
82 * - the transaction data is synced before the commit record is synced
83 * i.e. <transaction-data><roundoff> | <commit-rec><roundoff>
84 * Therefore the commit record is in its own Log Record.
85 * This can happen as the commit record is called with its
86 * own region to xlog_write().
87 * This then means that in the worst case, roundoff can happen for
88 * the commit-rec as well.
89 * The commit-rec is smaller than padding in this scenario and so it is
90 * not added separately.
91 */
92
93 /* for trans header */
94 unit_bytes += sizeof(xlog_op_header_t);
95 unit_bytes += sizeof(xfs_trans_header_t);
96
97 /* for start-rec */
98 unit_bytes += sizeof(xlog_op_header_t);
99
100 /*
101 * for LR headers - the space for data in an iclog is the size minus
102 * the space used for the headers. If we use the iclog size, then we
103 * undercalculate the number of headers required.
104 *
105 * Furthermore - the addition of op headers for split-recs might
106 * increase the space required enough to require more log and op
107 * headers, so take that into account too.
108 *
109 * IMPORTANT: This reservation makes the assumption that if this
110 * transaction is the first in an iclog and hence has the LR headers
111 * accounted to it, then the remaining space in the iclog is
112 * exclusively for this transaction. i.e. if the transaction is larger
113 * than the iclog, it will be the only thing in that iclog.
114 * Fundamentally, this means we must pass the entire log vector to
115 * xlog_write to guarantee this.
116 */
117 iclog_space = iclog_size - iclog_header_size;
118 num_headers = howmany(unit_bytes, iclog_space);
119
120 /* for split-recs - ophdrs added when data split over LRs */
121 unit_bytes += sizeof(xlog_op_header_t) * num_headers;
122
123 /* add extra header reservations if we overrun */
124 while (!num_headers ||
125 howmany(unit_bytes, iclog_space) > num_headers) {
126 unit_bytes += sizeof(xlog_op_header_t);
127 num_headers++;
128 }
129 unit_bytes += iclog_header_size * num_headers;
130
131 /* for commit-rec LR header - note: padding will subsume the ophdr */
132 unit_bytes += iclog_header_size;
133
134 /* for roundoff padding for transaction data and one for commit record */
135 if (xfs_sb_version_haslogv2(&mp->m_sb) && mp->m_sb.sb_logsunit > 1) {
136 /* log su roundoff */
137 unit_bytes += 2 * mp->m_sb.sb_logsunit;
138 } else {
139 /* BB roundoff */
140 unit_bytes += 2 * BBSIZE;
141 }
142
143 return unit_bytes;
144 }
145
146 /*
147 * Change the requested timestamp in the given inode.
148 *
149 * This was once shared with the kernel, but has diverged to the point
150 * where it's no longer worth the hassle of maintaining common code.
151 */
152 void
153 libxfs_trans_ichgtime(
154 struct xfs_trans *tp,
155 struct xfs_inode *ip,
156 int flags)
157 {
158 struct timespec tv;
159 struct timeval stv;
160
161 gettimeofday(&stv, (struct timezone *)0);
162 tv.tv_sec = stv.tv_sec;
163 tv.tv_nsec = stv.tv_usec * 1000;
164 if (flags & XFS_ICHGTIME_MOD)
165 VFS_I(ip)->i_mtime = tv;
166 if (flags & XFS_ICHGTIME_CHG)
167 VFS_I(ip)->i_ctime = tv;
168 if (flags & XFS_ICHGTIME_CREATE) {
169 ip->i_d.di_crtime.t_sec = (__int32_t)tv.tv_sec;
170 ip->i_d.di_crtime.t_nsec = (__int32_t)tv.tv_nsec;
171 }
172 }
173
174 /*
175 * Allocate an inode on disk and return a copy of its in-core version.
176 * Set mode, nlink, and rdev appropriately within the inode.
177 * The uid and gid for the inode are set according to the contents of
178 * the given cred structure.
179 *
180 * This was once shared with the kernel, but has diverged to the point
181 * where it's no longer worth the hassle of maintaining common code.
182 */
183 int
184 libxfs_ialloc(
185 xfs_trans_t *tp,
186 xfs_inode_t *pip,
187 mode_t mode,
188 nlink_t nlink,
189 xfs_dev_t rdev,
190 struct cred *cr,
191 struct fsxattr *fsx,
192 int okalloc,
193 xfs_buf_t **ialloc_context,
194 xfs_inode_t **ipp)
195 {
196 xfs_ino_t ino;
197 xfs_inode_t *ip;
198 uint flags;
199 int error;
200
201 /*
202 * Call the space management code to pick
203 * the on-disk inode to be allocated.
204 */
205 error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc,
206 ialloc_context, &ino);
207 if (error != 0)
208 return error;
209 if (*ialloc_context || ino == NULLFSINO) {
210 *ipp = NULL;
211 return 0;
212 }
213 ASSERT(*ialloc_context == NULL);
214
215 error = xfs_trans_iget(tp->t_mountp, tp, ino, 0, 0, &ip);
216 if (error != 0)
217 return error;
218 ASSERT(ip != NULL);
219
220 VFS_I(ip)->i_mode = mode;
221 set_nlink(VFS_I(ip), nlink);
222 ip->i_d.di_uid = cr->cr_uid;
223 ip->i_d.di_gid = cr->cr_gid;
224 xfs_set_projid(&ip->i_d, pip ? 0 : fsx->fsx_projid);
225 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD);
226
227 /*
228 * We only support filesystems that understand v2 format inodes. So if
229 * this is currently an old format inode, then change the inode version
230 * number now. This way we only do the conversion here rather than here
231 * and in the flush/logging code.
232 */
233 if (ip->i_d.di_version == 1) {
234 ip->i_d.di_version = 2;
235 /*
236 * old link count, projid_lo/hi field, pad field
237 * already zeroed
238 */
239 }
240
241 if (pip && (VFS_I(pip)->i_mode & S_ISGID)) {
242 ip->i_d.di_gid = pip->i_d.di_gid;
243 if ((VFS_I(pip)->i_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR)
244 VFS_I(ip)->i_mode |= S_ISGID;
245 }
246
247 ip->i_d.di_size = 0;
248 ip->i_d.di_nextents = 0;
249 ASSERT(ip->i_d.di_nblocks == 0);
250 ip->i_d.di_extsize = pip ? 0 : fsx->fsx_extsize;
251 ip->i_d.di_dmevmask = 0;
252 ip->i_d.di_dmstate = 0;
253 ip->i_d.di_flags = pip ? 0 : fsx->fsx_xflags;
254
255 if (ip->i_d.di_version == 3) {
256 ASSERT(ip->i_d.di_ino == ino);
257 ASSERT(uuid_equal(&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid));
258 VFS_I(ip)->i_version = 1;
259 ip->i_d.di_flags2 = 0;
260 ip->i_d.di_crtime.t_sec = (__int32_t)VFS_I(ip)->i_mtime.tv_sec;
261 ip->i_d.di_crtime.t_nsec = (__int32_t)VFS_I(ip)->i_mtime.tv_nsec;
262 }
263
264 flags = XFS_ILOG_CORE;
265 switch (mode & S_IFMT) {
266 case S_IFIFO:
267 case S_IFSOCK:
268 /* doesn't make sense to set an rdev for these */
269 rdev = 0;
270 /* FALLTHROUGH */
271 case S_IFCHR:
272 case S_IFBLK:
273 ip->i_d.di_format = XFS_DINODE_FMT_DEV;
274 ip->i_df.if_u2.if_rdev = rdev;
275 flags |= XFS_ILOG_DEV;
276 break;
277 case S_IFREG:
278 case S_IFDIR:
279 if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
280 uint di_flags = 0;
281
282 if ((mode & S_IFMT) == S_IFDIR) {
283 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
284 di_flags |= XFS_DIFLAG_RTINHERIT;
285 if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
286 di_flags |= XFS_DIFLAG_EXTSZINHERIT;
287 ip->i_d.di_extsize = pip->i_d.di_extsize;
288 }
289 } else {
290 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) {
291 di_flags |= XFS_DIFLAG_REALTIME;
292 }
293 if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
294 di_flags |= XFS_DIFLAG_EXTSIZE;
295 ip->i_d.di_extsize = pip->i_d.di_extsize;
296 }
297 }
298 if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
299 di_flags |= XFS_DIFLAG_PROJINHERIT;
300 ip->i_d.di_flags |= di_flags;
301 }
302 /* FALLTHROUGH */
303 case S_IFLNK:
304 ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
305 ip->i_df.if_flags = XFS_IFEXTENTS;
306 ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0;
307 ip->i_df.if_u1.if_extents = NULL;
308 break;
309 default:
310 ASSERT(0);
311 }
312 /* Attribute fork settings for new inode. */
313 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
314 ip->i_d.di_anextents = 0;
315
316 /*
317 * set up the inode ops structure that the libxfs code relies on
318 */
319 if (XFS_ISDIR(ip))
320 ip->d_ops = ip->i_mount->m_dir_inode_ops;
321 else
322 ip->d_ops = ip->i_mount->m_nondir_inode_ops;
323
324 /*
325 * Log the new values stuffed into the inode.
326 */
327 xfs_trans_log_inode(tp, ip, flags);
328 *ipp = ip;
329 return 0;
330 }
331
332 void
333 libxfs_iprint(
334 xfs_inode_t *ip)
335 {
336 struct xfs_icdinode *dip;
337 xfs_bmbt_rec_host_t *ep;
338 xfs_extnum_t i;
339 xfs_extnum_t nextents;
340
341 printf("Inode %lx\n", (unsigned long)ip);
342 printf(" i_ino %llx\n", (unsigned long long)ip->i_ino);
343
344 if (ip->i_df.if_flags & XFS_IFEXTENTS)
345 printf("EXTENTS ");
346 printf("\n");
347 printf(" i_df.if_bytes %d\n", ip->i_df.if_bytes);
348 printf(" i_df.if_u1.if_extents/if_data %lx\n",
349 (unsigned long)ip->i_df.if_u1.if_extents);
350 if (ip->i_df.if_flags & XFS_IFEXTENTS) {
351 nextents = ip->i_df.if_bytes / (uint)sizeof(*ep);
352 for (ep = ip->i_df.if_u1.if_extents, i = 0; i < nextents;
353 i++, ep++) {
354 xfs_bmbt_irec_t rec;
355
356 xfs_bmbt_get_all(ep, &rec);
357 printf("\t%d: startoff %llu, startblock 0x%llx,"
358 " blockcount %llu, state %d\n",
359 i, (unsigned long long)rec.br_startoff,
360 (unsigned long long)rec.br_startblock,
361 (unsigned long long)rec.br_blockcount,
362 (int)rec.br_state);
363 }
364 }
365 printf(" i_df.if_broot %lx\n", (unsigned long)ip->i_df.if_broot);
366 printf(" i_df.if_broot_bytes %x\n", ip->i_df.if_broot_bytes);
367
368 dip = &ip->i_d;
369 printf("\nOn disk portion\n");
370 printf(" di_mode %o\n", VFS_I(ip)->i_mode);
371 printf(" di_version %x\n", (uint)dip->di_version);
372 switch (ip->i_d.di_format) {
373 case XFS_DINODE_FMT_LOCAL:
374 printf(" Inline inode\n");
375 break;
376 case XFS_DINODE_FMT_EXTENTS:
377 printf(" Extents inode\n");
378 break;
379 case XFS_DINODE_FMT_BTREE:
380 printf(" B-tree inode\n");
381 break;
382 default:
383 printf(" Other inode\n");
384 break;
385 }
386 printf(" di_nlink %x\n", VFS_I(ip)->i_nlink);
387 printf(" di_uid %d\n", dip->di_uid);
388 printf(" di_gid %d\n", dip->di_gid);
389 printf(" di_nextents %d\n", dip->di_nextents);
390 printf(" di_size %llu\n", (unsigned long long)dip->di_size);
391 printf(" di_gen %x\n", VFS_I(ip)->i_generation);
392 printf(" di_extsize %d\n", dip->di_extsize);
393 printf(" di_flags %x\n", dip->di_flags);
394 printf(" di_nblocks %llu\n", (unsigned long long)dip->di_nblocks);
395 }
396
397 /*
398 * Writes a modified inode's changes out to the inode's on disk home.
399 * Originally based on xfs_iflush_int() from xfs_inode.c in the kernel.
400 */
401 int
402 libxfs_iflush_int(xfs_inode_t *ip, xfs_buf_t *bp)
403 {
404 xfs_inode_log_item_t *iip;
405 xfs_dinode_t *dip;
406 xfs_mount_t *mp;
407
408 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
409 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
410 ip->i_d.di_nextents > ip->i_df.if_ext_max);
411 ASSERT(ip->i_d.di_version > 1);
412
413 iip = ip->i_itemp;
414 mp = ip->i_mount;
415
416 /* set *dip = inode's place in the buffer */
417 dip = xfs_buf_offset(bp, ip->i_imap.im_boffset);
418
419 ASSERT(ip->i_d.di_magic == XFS_DINODE_MAGIC);
420 if (XFS_ISREG(ip)) {
421 ASSERT( (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS) ||
422 (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) );
423 } else if (XFS_ISDIR(ip)) {
424 ASSERT( (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS) ||
425 (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) ||
426 (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) );
427 }
428 ASSERT(ip->i_d.di_nextents+ip->i_d.di_anextents <= ip->i_d.di_nblocks);
429 ASSERT(ip->i_d.di_forkoff <= mp->m_sb.sb_inodesize);
430
431 /* bump the change count on v3 inodes */
432 if (ip->i_d.di_version == 3)
433 VFS_I(ip)->i_version++;
434
435 /*
436 * Copy the dirty parts of the inode into the on-disk
437 * inode. We always copy out the core of the inode,
438 * because if the inode is dirty at all the core must
439 * be.
440 */
441 xfs_inode_to_disk(ip, dip, iip->ili_item.li_lsn);
442
443 xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK);
444 if (XFS_IFORK_Q(ip))
445 xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK);
446
447 /* generate the checksum. */
448 xfs_dinode_calc_crc(mp, dip);
449
450 return 0;
451 }
452
453 int
454 libxfs_mod_incore_sb(
455 struct xfs_mount *mp,
456 int field,
457 int64_t delta,
458 int rsvd)
459 {
460 long long lcounter; /* long counter for 64 bit fields */
461
462 switch (field) {
463 case XFS_TRANS_SB_FDBLOCKS:
464 lcounter = (long long)mp->m_sb.sb_fdblocks;
465 lcounter += delta;
466 if (lcounter < 0)
467 return -ENOSPC;
468 mp->m_sb.sb_fdblocks = lcounter;
469 return 0;
470 default:
471 ASSERT(0);
472 return -EINVAL;
473 }
474 }
475
476 int
477 libxfs_bmap_finish(
478 struct xfs_trans **tp,
479 struct xfs_bmap_free *flist,
480 struct xfs_inode *ip)
481 {
482 xfs_bmap_free_item_t *free; /* free extent list item */
483 xfs_bmap_free_item_t *next; /* next item on free list */
484 int error;
485
486 if (flist->xbf_count == 0)
487 return 0;
488
489 for (free = flist->xbf_first; free != NULL; free = next) {
490 next = free->xbfi_next;
491 error = xfs_free_extent(*tp, free->xbfi_startblock,
492 free->xbfi_blockcount);
493 if (error)
494 return error;
495 xfs_bmap_del_free(flist, NULL, free);
496 }
497 return 0;
498 }
499
500 /*
501 * This routine allocates disk space for the given file.
502 * Originally derived from xfs_alloc_file_space().
503 */
504 int
505 libxfs_alloc_file_space(
506 xfs_inode_t *ip,
507 xfs_off_t offset,
508 xfs_off_t len,
509 int alloc_type,
510 int attr_flags)
511 {
512 xfs_mount_t *mp;
513 xfs_off_t count;
514 xfs_filblks_t datablocks;
515 xfs_filblks_t allocated_fsb;
516 xfs_filblks_t allocatesize_fsb;
517 xfs_fsblock_t firstfsb;
518 xfs_bmap_free_t free_list;
519 xfs_bmbt_irec_t *imapp;
520 xfs_bmbt_irec_t imaps[1];
521 int reccount;
522 uint resblks;
523 xfs_fileoff_t startoffset_fsb;
524 xfs_trans_t *tp;
525 int xfs_bmapi_flags;
526 int error;
527
528 if (len <= 0)
529 return -EINVAL;
530
531 count = len;
532 error = 0;
533 imapp = &imaps[0];
534 reccount = 1;
535 xfs_bmapi_flags = alloc_type ? XFS_BMAPI_PREALLOC : 0;
536 mp = ip->i_mount;
537 startoffset_fsb = XFS_B_TO_FSBT(mp, offset);
538 allocatesize_fsb = XFS_B_TO_FSB(mp, count);
539
540 /* allocate file space until done or until there is an error */
541 while (allocatesize_fsb && !error) {
542 datablocks = allocatesize_fsb;
543
544 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
545 resblks = (uint)XFS_DIOSTRAT_SPACE_RES(mp, datablocks);
546 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
547 resblks, 0);
548 /*
549 * Check for running out of space
550 */
551 if (error) {
552 /*
553 * Free the transaction structure.
554 */
555 ASSERT(error == -ENOSPC);
556 xfs_trans_cancel(tp);
557 break;
558 }
559 xfs_trans_ijoin(tp, ip, 0);
560
561 xfs_bmap_init(&free_list, &firstfsb);
562 error = xfs_bmapi_write(tp, ip, startoffset_fsb, allocatesize_fsb,
563 xfs_bmapi_flags, &firstfsb, 0, imapp,
564 &reccount, &free_list);
565
566 if (error)
567 goto error0;
568
569 /* complete the transaction */
570 error = xfs_bmap_finish(&tp, &free_list, ip);
571 if (error)
572 goto error0;
573
574 error = xfs_trans_commit(tp);
575 if (error)
576 break;
577
578 allocated_fsb = imapp->br_blockcount;
579 if (reccount == 0)
580 return -ENOSPC;
581
582 startoffset_fsb += allocated_fsb;
583 allocatesize_fsb -= allocated_fsb;
584 }
585 return error;
586
587 error0: /* Cancel bmap, cancel trans */
588 xfs_bmap_cancel(&free_list);
589 xfs_trans_cancel(tp);
590 return error;
591 }
592
593 unsigned int
594 libxfs_log2_roundup(unsigned int i)
595 {
596 unsigned int rval;
597
598 for (rval = 0; rval < NBBY * sizeof(i); rval++) {
599 if ((1 << rval) >= i)
600 break;
601 }
602 return rval;
603 }
604
605 /*
606 * Wrapper around call to libxfs_ialloc. Takes care of committing and
607 * allocating a new transaction as needed.
608 *
609 * Originally there were two copies of this code - one in mkfs, the
610 * other in repair - now there is just the one.
611 */
612 int
613 libxfs_inode_alloc(
614 xfs_trans_t **tp,
615 xfs_inode_t *pip,
616 mode_t mode,
617 nlink_t nlink,
618 xfs_dev_t rdev,
619 struct cred *cr,
620 struct fsxattr *fsx,
621 xfs_inode_t **ipp)
622 {
623 xfs_buf_t *ialloc_context;
624 xfs_inode_t *ip;
625 int error;
626
627 ialloc_context = (xfs_buf_t *)0;
628 error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr, fsx,
629 1, &ialloc_context, &ip);
630 if (error) {
631 *ipp = NULL;
632 return error;
633 }
634 if (!ialloc_context && !ip) {
635 *ipp = NULL;
636 return -ENOSPC;
637 }
638
639 if (ialloc_context) {
640
641 xfs_trans_bhold(*tp, ialloc_context);
642
643 error = xfs_trans_roll(tp, NULL);
644 if (error) {
645 fprintf(stderr, _("%s: cannot duplicate transaction: %s\n"),
646 progname, strerror(error));
647 exit(1);
648 }
649 xfs_trans_bjoin(*tp, ialloc_context);
650 error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr,
651 fsx, 1, &ialloc_context, &ip);
652 if (!ip)
653 error = -ENOSPC;
654 if (error)
655 return error;
656 }
657
658 *ipp = ip;
659 return error;
660 }
661
662 /*
663 * Userspace versions of common diagnostic routines (varargs fun).
664 */
665 void
666 libxfs_fs_repair_cmn_err(int level, xfs_mount_t *mp, char *fmt, ...)
667 {
668 va_list ap;
669
670 va_start(ap, fmt);
671 vfprintf(stderr, fmt, ap);
672 fprintf(stderr, " This is a bug.\n");
673 fprintf(stderr, "%s version %s\n", progname, VERSION);
674 fprintf(stderr, "Please capture the filesystem metadata with "
675 "xfs_metadump and\nreport it to xfs@oss.sgi.com.\n");
676 va_end(ap);
677 }
678
679 void
680 libxfs_fs_cmn_err(int level, xfs_mount_t *mp, char *fmt, ...)
681 {
682 va_list ap;
683
684 va_start(ap, fmt);
685 vfprintf(stderr, fmt, ap);
686 fputs("\n", stderr);
687 va_end(ap);
688 }
689
690 void
691 cmn_err(int level, char *fmt, ...)
692 {
693 va_list ap;
694
695 va_start(ap, fmt);
696 vfprintf(stderr, fmt, ap);
697 fputs("\n", stderr);
698 va_end(ap);
699 }
700
701 /*
702 * Warnings specifically for verifier errors. Differentiate CRC vs. invalid
703 * values, and omit the stack trace unless the error level is tuned high.
704 */
705 void
706 xfs_verifier_error(
707 struct xfs_buf *bp)
708 {
709 xfs_alert(NULL, "Metadata %s detected at %s block 0x%llx/0x%x",
710 bp->b_error == -EFSBADCRC ? "CRC error" : "corruption",
711 bp->b_ops->name, bp->b_bn, BBTOB(bp->b_length));
712 }
713
714 /*
715 * This is called from I/O verifiers on v5 superblock filesystems. In the
716 * kernel, it validates the metadata LSN parameter against the current LSN of
717 * the active log. We don't have an active log in userspace so this kind of
718 * validation is not required. Therefore, this function always returns true in
719 * userspace.
720 *
721 * xfs_repair piggybacks off this mechanism to help track the largest metadata
722 * LSN in use on a filesystem. Keep a record of the largest LSN seen such that
723 * repair can validate it against the state of the log.
724 */
725 xfs_lsn_t libxfs_max_lsn = 0;
726 pthread_mutex_t libxfs_max_lsn_lock = PTHREAD_MUTEX_INITIALIZER;
727
728 bool
729 xfs_log_check_lsn(
730 struct xfs_mount *mp,
731 xfs_lsn_t lsn)
732 {
733 int cycle = CYCLE_LSN(lsn);
734 int block = BLOCK_LSN(lsn);
735 int max_cycle;
736 int max_block;
737
738 if (lsn == NULLCOMMITLSN)
739 return true;
740
741 pthread_mutex_lock(&libxfs_max_lsn_lock);
742
743 max_cycle = CYCLE_LSN(libxfs_max_lsn);
744 max_block = BLOCK_LSN(libxfs_max_lsn);
745
746 if ((cycle > max_cycle) ||
747 (cycle == max_cycle && block > max_block))
748 libxfs_max_lsn = lsn;
749
750 pthread_mutex_unlock(&libxfs_max_lsn_lock);
751
752 return true;
753 }
754
755 static struct xfs_buftarg *
756 xfs_find_bdev_for_inode(
757 struct xfs_inode *ip)
758 {
759 struct xfs_mount *mp = ip->i_mount;
760
761 if (XFS_IS_REALTIME_INODE(ip))
762 return mp->m_rtdev_targp;
763 return mp->m_ddev_targp;
764 }
765
766 static xfs_daddr_t
767 xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb)
768 {
769 if (XFS_IS_REALTIME_INODE(ip))
770 return XFS_FSB_TO_BB(ip->i_mount, fsb);
771 return XFS_FSB_TO_DADDR(ip->i_mount, (fsb));
772 }
773
774 int
775 libxfs_zero_extent(
776 struct xfs_inode *ip,
777 xfs_fsblock_t start_fsb,
778 xfs_off_t count_fsb)
779 {
780 xfs_daddr_t sector = xfs_fsb_to_db(ip, start_fsb);
781 ssize_t size = XFS_FSB_TO_BB(ip->i_mount, count_fsb);
782
783 return libxfs_device_zero(xfs_find_bdev_for_inode(ip), sector, size);
784 }