1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
10 #include "libxfs_priv.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 #include "libfrog/platform.h"
26 #include "libxfs.h" /* for now */
28 char *progname
= "libxfs"; /* default, changed by each tool */
30 struct cache
*libxfs_bcache
; /* global buffer cache */
31 int libxfs_bhash_size
; /* #buckets in bcache */
33 int use_xfs_buf_lock
; /* global flag: use xfs_buf_t locks for MT */
36 * dev_map - map open devices to fd.
38 #define MAX_DEVS 10 /* arbitary maximum */
39 static int nextfakedev
= -1; /* device number to give to next fake device */
40 static struct dev_to_fd
{
43 } dev_map
[MAX_DEVS
]={{0}};
46 * Checks whether a given device has a mounted, writable
47 * filesystem, returns 1 if it does & fatal (just warns
48 * if not fatal, but allows us to proceed).
50 * Useful to tools which will produce uncertain results
51 * if the filesystem is active - repair, check, logprint.
54 check_isactive(char *name
, char *block
, int fatal
)
58 if (stat(block
, &st
) < 0)
60 if ((st
.st_mode
& S_IFMT
) != S_IFBLK
)
62 if (platform_check_ismounted(name
, block
, &st
, 0) == 0)
64 if (platform_check_iswritable(name
, block
, &st
))
69 /* libxfs_device_to_fd:
70 * lookup a device number in the device map
71 * return the associated fd
74 libxfs_device_to_fd(dev_t device
)
78 for (d
= 0; d
< MAX_DEVS
; d
++)
79 if (dev_map
[d
].dev
== device
)
82 fprintf(stderr
, _("%s: %s: device %lld is not open\n"),
83 progname
, __FUNCTION__
, (long long)device
);
88 /* libxfs_device_open:
89 * open a device and return its device number
92 libxfs_device_open(char *path
, int creat
, int xflags
, int setblksize
)
96 int readonly
, dio
, excl
;
99 readonly
= (xflags
& LIBXFS_ISREADONLY
);
100 excl
= (xflags
& LIBXFS_EXCLUSIVELY
) && !creat
;
101 dio
= (xflags
& LIBXFS_DIRECT
) && !creat
&& platform_direct_blockdev();
104 flags
= (readonly
? O_RDONLY
: O_RDWR
) | \
105 (creat
? (O_CREAT
|O_TRUNC
) : 0) | \
106 (dio
? O_DIRECT
: 0) | \
109 if ((fd
= open(path
, flags
, 0666)) < 0) {
110 if (errno
== EINVAL
&& --dio
== 0)
112 fprintf(stderr
, _("%s: cannot open %s: %s\n"),
113 progname
, path
, strerror(errno
));
117 if (fstat(fd
, &statb
) < 0) {
118 fprintf(stderr
, _("%s: cannot stat %s: %s\n"),
119 progname
, path
, strerror(errno
));
123 if (!readonly
&& setblksize
&& (statb
.st_mode
& S_IFMT
) == S_IFBLK
) {
125 /* use the default blocksize */
126 (void)platform_set_blocksize(fd
, path
, statb
.st_rdev
, XFS_MIN_SECTORSIZE
, 0);
128 /* given an explicit blocksize to use */
129 if (platform_set_blocksize(fd
, path
, statb
.st_rdev
, setblksize
, 1))
135 * Get the device number from the stat buf - unless
136 * we're not opening a real device, in which case
137 * choose a new fake device number.
139 dev
= (statb
.st_rdev
) ? (statb
.st_rdev
) : (nextfakedev
--);
141 for (d
= 0; d
< MAX_DEVS
; d
++)
142 if (dev_map
[d
].dev
== dev
) {
143 fprintf(stderr
, _("%s: device %lld is already open\n"),
144 progname
, (long long)dev
);
148 for (d
= 0; d
< MAX_DEVS
; d
++)
149 if (!dev_map
[d
].dev
) {
150 dev_map
[d
].dev
= dev
;
156 fprintf(stderr
, _("%s: %s: too many open devices\n"),
157 progname
, __FUNCTION__
);
163 libxfs_device_close(dev_t dev
)
167 for (d
= 0; d
< MAX_DEVS
; d
++)
168 if (dev_map
[d
].dev
== dev
) {
172 dev_map
[d
].dev
= dev_map
[d
].fd
= 0;
175 platform_flush_device(fd
, dev
);
181 fprintf(stderr
, _("%s: %s: device %lld is not open\n"),
182 progname
, __FUNCTION__
, (long long)dev
);
187 check_open(char *path
, int flags
, char **rawfile
, char **blockfile
)
189 int readonly
= (flags
& LIBXFS_ISREADONLY
);
190 int inactive
= (flags
& LIBXFS_ISINACTIVE
);
191 int dangerously
= (flags
& LIBXFS_DANGEROUSLY
);
194 if (stat(path
, &stbuf
) < 0) {
198 if (!(*rawfile
= platform_findrawpath(path
))) {
199 fprintf(stderr
, _("%s: "
200 "can't find a character device matching %s\n"),
204 if (!(*blockfile
= platform_findblockpath(path
))) {
205 fprintf(stderr
, _("%s: "
206 "can't find a block device matching %s\n"),
210 if (!readonly
&& !inactive
&& platform_check_ismounted(path
, *blockfile
, NULL
, 1))
213 if (inactive
&& check_isactive(path
, *blockfile
, ((readonly
|dangerously
)?1:0)))
220 * Initialize/destroy all of the zone allocators we use.
225 /* initialise zone allocation */
226 xfs_buf_zone
= kmem_zone_init(sizeof(struct xfs_buf
), "xfs_buffer");
227 xfs_inode_zone
= kmem_zone_init(sizeof(struct xfs_inode
), "xfs_inode");
228 xfs_ifork_zone
= kmem_zone_init(sizeof(struct xfs_ifork
), "xfs_ifork");
229 xfs_ili_zone
= kmem_zone_init(
230 sizeof(struct xfs_inode_log_item
),"xfs_inode_log_item");
231 xfs_buf_item_zone
= kmem_zone_init(
232 sizeof(struct xfs_buf_log_item
), "xfs_buf_log_item");
233 xfs_da_state_zone
= kmem_zone_init(
234 sizeof(struct xfs_da_state
), "xfs_da_state");
235 xfs_btree_cur_zone
= kmem_zone_init(
236 sizeof(struct xfs_btree_cur
), "xfs_btree_cur");
237 xfs_bmap_free_item_zone
= kmem_zone_init(
238 sizeof(struct xfs_extent_free_item
),
239 "xfs_bmap_free_item");
240 xfs_trans_zone
= kmem_zone_init(
241 sizeof(struct xfs_trans
), "xfs_trans");
249 leaked
+= kmem_zone_destroy(xfs_buf_zone
);
250 leaked
+= kmem_zone_destroy(xfs_ili_zone
);
251 leaked
+= kmem_zone_destroy(xfs_inode_zone
);
252 leaked
+= kmem_zone_destroy(xfs_ifork_zone
);
253 leaked
+= kmem_zone_destroy(xfs_buf_item_zone
);
254 leaked
+= kmem_zone_destroy(xfs_da_state_zone
);
255 leaked
+= kmem_zone_destroy(xfs_btree_cur_zone
);
256 leaked
+= kmem_zone_destroy(xfs_bmap_free_item_zone
);
257 leaked
+= kmem_zone_destroy(xfs_trans_zone
);
263 libxfs_close_devices(
264 struct libxfs_xinit
*li
)
267 libxfs_device_close(li
->ddev
);
268 if (li
->logdev
&& li
->logdev
!= li
->ddev
)
269 libxfs_device_close(li
->logdev
);
271 libxfs_device_close(li
->rtdev
);
273 li
->ddev
= li
->logdev
= li
->rtdev
= 0;
274 li
->dfd
= li
->logfd
= li
->rtfd
= -1;
278 * libxfs initialization.
279 * Caller gets a 0 on failure (and we print a message), 1 on success.
282 libxfs_init(libxfs_init_t
*a
)
296 dpath
[0] = logpath
[0] = rtpath
[0] = '\0';
298 logname
= a
->logname
;
300 a
->dfd
= a
->logfd
= a
->rtfd
= -1;
301 a
->ddev
= a
->logdev
= a
->rtdev
= 0;
302 a
->dsize
= a
->lbsize
= a
->rtbsize
= 0;
303 a
->dbsize
= a
->logBBsize
= a
->logBBstart
= a
->rtsize
= 0;
306 flags
= (a
->isreadonly
| a
->isdirect
);
311 if(!check_open(a
->volname
,flags
,&rawfile
,&blockfile
))
313 fd
= open(rawfile
, O_RDONLY
);
314 dname
= a
->dname
= a
->volname
;
319 a
->ddev
= libxfs_device_open(dname
, a
->dcreat
, flags
,
321 a
->dfd
= libxfs_device_to_fd(a
->ddev
);
322 platform_findsizes(dname
, a
->dfd
, &a
->dsize
,
325 if (!check_open(dname
, flags
, &rawfile
, &blockfile
))
327 a
->ddev
= libxfs_device_open(rawfile
,
328 a
->dcreat
, flags
, a
->setblksize
);
329 a
->dfd
= libxfs_device_to_fd(a
->ddev
);
330 platform_findsizes(rawfile
, a
->dfd
,
331 &a
->dsize
, &a
->dbsize
);
337 a
->logdev
= libxfs_device_open(logname
,
338 a
->lcreat
, flags
, a
->setblksize
);
339 a
->logfd
= libxfs_device_to_fd(a
->logdev
);
340 platform_findsizes(dname
, a
->logfd
, &a
->logBBsize
,
343 if (!check_open(logname
, flags
, &rawfile
, &blockfile
))
345 a
->logdev
= libxfs_device_open(rawfile
,
346 a
->lcreat
, flags
, a
->setblksize
);
347 a
->logfd
= libxfs_device_to_fd(a
->logdev
);
348 platform_findsizes(rawfile
, a
->logfd
,
349 &a
->logBBsize
, &a
->lbsize
);
355 a
->rtdev
= libxfs_device_open(rtname
,
356 a
->rcreat
, flags
, a
->setblksize
);
357 a
->rtfd
= libxfs_device_to_fd(a
->rtdev
);
358 platform_findsizes(dname
, a
->rtfd
, &a
->rtsize
,
361 if (!check_open(rtname
, flags
, &rawfile
, &blockfile
))
363 a
->rtdev
= libxfs_device_open(rawfile
,
364 a
->rcreat
, flags
, a
->setblksize
);
365 a
->rtfd
= libxfs_device_to_fd(a
->rtdev
);
366 platform_findsizes(rawfile
, a
->rtfd
,
367 &a
->rtsize
, &a
->rtbsize
);
372 fprintf(stderr
, _("%s: can't get size for data subvolume\n"),
376 if (a
->logBBsize
< 0) {
377 fprintf(stderr
, _("%s: can't get size for log subvolume\n"),
382 fprintf(stderr
, _("%s: can't get size for realtime subvolume\n"),
386 if (!libxfs_bhash_size
)
387 libxfs_bhash_size
= LIBXFS_BHASHSIZE(sbp
);
388 libxfs_bcache
= cache_init(a
->bcache_flags
, libxfs_bhash_size
,
389 &libxfs_bcache_operations
);
390 use_xfs_buf_lock
= a
->usebuflock
;
404 libxfs_close_devices(a
);
411 * Initialize realtime fields in the mount structure.
415 xfs_mount_t
*mp
, /* file system mount structure */
418 xfs_buf_t
*bp
; /* buffer for last block of subvolume */
419 xfs_daddr_t d
; /* address of last block of subvolume */
420 xfs_sb_t
*sbp
; /* filesystem superblock copy in mount */
423 if (sbp
->sb_rblocks
== 0)
425 if (mp
->m_rtdev_targp
->dev
== 0 && !(flags
& LIBXFS_MOUNT_DEBUGGER
)) {
426 fprintf(stderr
, _("%s: filesystem has a realtime subvolume\n"),
430 mp
->m_rsumlevels
= sbp
->sb_rextslog
+ 1;
432 (uint
)sizeof(xfs_suminfo_t
) * mp
->m_rsumlevels
*
434 mp
->m_rsumsize
= roundup(mp
->m_rsumsize
, sbp
->sb_blocksize
);
435 mp
->m_rbmip
= mp
->m_rsumip
= NULL
;
438 * Allow debugger to be run without the realtime device present.
440 if (flags
& LIBXFS_MOUNT_DEBUGGER
)
444 * Check that the realtime section is an ok size.
446 d
= (xfs_daddr_t
)XFS_FSB_TO_BB(mp
, mp
->m_sb
.sb_rblocks
);
447 if (XFS_BB_TO_FSB(mp
, d
) != mp
->m_sb
.sb_rblocks
) {
448 fprintf(stderr
, _("%s: realtime init - %llu != %llu\n"),
449 progname
, (unsigned long long) XFS_BB_TO_FSB(mp
, d
),
450 (unsigned long long) mp
->m_sb
.sb_rblocks
);
453 bp
= libxfs_readbuf(mp
->m_rtdev
,
454 d
- XFS_FSB_TO_BB(mp
, 1), XFS_FSB_TO_BB(mp
, 1), 0, NULL
);
456 fprintf(stderr
, _("%s: realtime size check failed\n"),
465 libxfs_initialize_perag(
467 xfs_agnumber_t agcount
,
468 xfs_agnumber_t
*maxagi
)
470 xfs_agnumber_t index
, max_metadata
;
471 xfs_agnumber_t first_initialised
= 0;
475 xfs_sb_t
*sbp
= &mp
->m_sb
;
479 * Walk the current per-ag tree so we don't try to initialise AGs
480 * that already exist (growfs case). Allocate and insert all the
481 * AGs we don't find ready for initialisation.
483 for (index
= 0; index
< agcount
; index
++) {
484 pag
= xfs_perag_get(mp
, index
);
489 if (!first_initialised
)
490 first_initialised
= index
;
492 pag
= kmem_zalloc(sizeof(*pag
), KM_MAYFAIL
);
495 pag
->pag_agno
= index
;
498 if (radix_tree_insert(&mp
->m_perag_tree
, index
, pag
)) {
505 * If we mount with the inode64 option, or no inode overflows
506 * the legacy 32-bit address space clear the inode32 option.
508 agino
= XFS_AGB_TO_AGINO(mp
, sbp
->sb_agblocks
- 1);
509 ino
= XFS_AGINO_TO_INO(mp
, agcount
- 1, agino
);
511 if ((mp
->m_flags
& XFS_MOUNT_SMALL_INUMS
) && ino
> XFS_MAXINUMBER_32
)
512 mp
->m_flags
|= XFS_MOUNT_32BITINODES
;
514 mp
->m_flags
&= ~XFS_MOUNT_32BITINODES
;
516 if (mp
->m_flags
& XFS_MOUNT_32BITINODES
) {
518 * Calculate how much should be reserved for inodes to meet
519 * the max inode percentage.
521 if (M_IGEO(mp
)->maxicount
) {
524 icount
= sbp
->sb_dblocks
* sbp
->sb_imax_pct
;
526 icount
+= sbp
->sb_agblocks
- 1;
527 do_div(icount
, sbp
->sb_agblocks
);
528 max_metadata
= icount
;
530 max_metadata
= agcount
;
533 for (index
= 0; index
< agcount
; index
++) {
534 ino
= XFS_AGINO_TO_INO(mp
, index
, agino
);
535 if (ino
> XFS_MAXINUMBER_32
) {
540 pag
= xfs_perag_get(mp
, index
);
541 pag
->pagi_inodeok
= 1;
542 if (index
< max_metadata
)
543 pag
->pagf_metadata
= 1;
547 for (index
= 0; index
< agcount
; index
++) {
548 pag
= xfs_perag_get(mp
, index
);
549 pag
->pagi_inodeok
= 1;
557 mp
->m_ag_prealloc_blocks
= xfs_prealloc_blocks(mp
);
562 for (; index
> first_initialised
; index
--) {
563 pag
= radix_tree_delete(&mp
->m_perag_tree
, index
);
569 static struct xfs_buftarg
*
570 libxfs_buftarg_alloc(
571 struct xfs_mount
*mp
,
574 struct xfs_buftarg
*btp
;
576 btp
= malloc(sizeof(*btp
));
578 fprintf(stderr
, _("%s: buftarg init failed\n"),
589 struct xfs_mount
*mp
,
594 if (mp
->m_ddev_targp
) {
595 /* should already have all buftargs initialised */
596 if (mp
->m_ddev_targp
->dev
!= dev
||
597 mp
->m_ddev_targp
->bt_mount
!= mp
) {
599 _("%s: bad buftarg reinit, ddev\n"),
603 if (!logdev
|| logdev
== dev
) {
604 if (mp
->m_logdev_targp
!= mp
->m_ddev_targp
) {
606 _("%s: bad buftarg reinit, ldev mismatch\n"),
610 } else if (mp
->m_logdev_targp
->dev
!= logdev
||
611 mp
->m_logdev_targp
->bt_mount
!= mp
) {
613 _("%s: bad buftarg reinit, logdev\n"),
617 if (rtdev
&& (mp
->m_rtdev_targp
->dev
!= rtdev
||
618 mp
->m_rtdev_targp
->bt_mount
!= mp
)) {
620 _("%s: bad buftarg reinit, rtdev\n"),
627 mp
->m_ddev_targp
= libxfs_buftarg_alloc(mp
, dev
);
628 if (!logdev
|| logdev
== dev
)
629 mp
->m_logdev_targp
= mp
->m_ddev_targp
;
631 mp
->m_logdev_targp
= libxfs_buftarg_alloc(mp
, logdev
);
632 mp
->m_rtdev_targp
= libxfs_buftarg_alloc(mp
, rtdev
);
636 * Mount structure initialization, provides a filled-in xfs_mount_t
637 * such that the numerous XFS_* macros can be used. If dev is zero,
638 * no IO will be performed (no size checks, read root inodes).
654 libxfs_buftarg_init(mp
, dev
, logdev
, rtdev
);
656 mp
->m_finobt_nores
= true;
657 mp
->m_flags
= (LIBXFS_MOUNT_32BITINODES
|LIBXFS_MOUNT_32BITINOOPT
);
659 INIT_RADIX_TREE(&mp
->m_perag_tree
, GFP_KERNEL
);
662 xfs_sb_mount_common(mp
, sb
);
665 * Set whether we're using stripe alignment.
667 if (xfs_sb_version_hasdalign(&mp
->m_sb
)) {
668 mp
->m_dalign
= sbp
->sb_unit
;
669 mp
->m_swidth
= sbp
->sb_width
;
672 xfs_alloc_compute_maxlevels(mp
);
673 xfs_bmap_compute_maxlevels(mp
, XFS_DATA_FORK
);
674 xfs_bmap_compute_maxlevels(mp
, XFS_ATTR_FORK
);
675 xfs_ialloc_setup_geometry(mp
);
676 xfs_rmapbt_compute_maxlevels(mp
);
677 xfs_refcountbt_compute_maxlevels(mp
);
680 * Check that the data (and log if separate) are an ok size.
682 d
= (xfs_daddr_t
) XFS_FSB_TO_BB(mp
, mp
->m_sb
.sb_dblocks
);
683 if (XFS_BB_TO_FSB(mp
, d
) != mp
->m_sb
.sb_dblocks
) {
684 fprintf(stderr
, _("%s: size check failed\n"), progname
);
685 if (!(flags
& LIBXFS_MOUNT_DEBUGGER
))
690 * We automatically convert v1 inodes to v2 inodes now, so if
691 * the NLINK bit is not set we can't operate on the filesystem.
693 if (!(sbp
->sb_versionnum
& XFS_SB_VERSION_NLINKBIT
)) {
696 "%s: V1 inodes unsupported. Please try an older xfsprogs.\n"),
701 /* Check for supported directory formats */
702 if (!(sbp
->sb_versionnum
& XFS_SB_VERSION_DIRV2BIT
)) {
705 "%s: V1 directories unsupported. Please try an older xfsprogs.\n"),
710 /* check for unsupported other features */
711 if (!xfs_sb_good_version(sbp
)) {
713 "%s: Unsupported features detected. Please try a newer xfsprogs.\n"),
720 if (xfs_sb_version_hasattr2(&mp
->m_sb
))
721 mp
->m_flags
|= LIBXFS_MOUNT_ATTR2
;
723 /* Initialize the precomputed transaction reservations values */
726 if (dev
== 0) /* maxtrres, we have no device so leave now */
729 bp
= libxfs_readbuf(mp
->m_dev
,
730 d
- XFS_FSS_TO_BB(mp
, 1), XFS_FSS_TO_BB(mp
, 1),
731 !(flags
& LIBXFS_MOUNT_DEBUGGER
), NULL
);
733 fprintf(stderr
, _("%s: data size check failed\n"), progname
);
734 if (!(flags
& LIBXFS_MOUNT_DEBUGGER
))
739 if (mp
->m_logdev_targp
->dev
&&
740 mp
->m_logdev_targp
->dev
!= mp
->m_ddev_targp
->dev
) {
741 d
= (xfs_daddr_t
) XFS_FSB_TO_BB(mp
, mp
->m_sb
.sb_logblocks
);
742 if ( (XFS_BB_TO_FSB(mp
, d
) != mp
->m_sb
.sb_logblocks
) ||
743 (!(bp
= libxfs_readbuf(mp
->m_logdev_targp
,
744 d
- XFS_FSB_TO_BB(mp
, 1),
745 XFS_FSB_TO_BB(mp
, 1),
746 !(flags
& LIBXFS_MOUNT_DEBUGGER
), NULL
))) ) {
747 fprintf(stderr
, _("%s: log size checks failed\n"),
749 if (!(flags
& LIBXFS_MOUNT_DEBUGGER
))
756 /* Initialize realtime fields in the mount structure */
757 if (rtmount_init(mp
, flags
)) {
758 fprintf(stderr
, _("%s: realtime device init failed\n"),
764 * libxfs_initialize_perag will allocate a perag structure for each ag.
765 * If agcount is corrupted and insanely high, this will OOM the box.
766 * If the agount seems (arbitrarily) high, try to read what would be
767 * the last AG, and if that fails for a relatively high agcount, just
768 * read the first one and let the user know to check the geometry.
770 if (sbp
->sb_agcount
> 1000000) {
771 bp
= libxfs_readbuf(mp
->m_dev
,
772 XFS_AG_DADDR(mp
, sbp
->sb_agcount
- 1, 0), 1,
773 !(flags
& LIBXFS_MOUNT_DEBUGGER
), NULL
);
775 fprintf(stderr
, _("%s: read of AG %u failed\n"),
776 progname
, sbp
->sb_agcount
);
777 if (!(flags
& LIBXFS_MOUNT_DEBUGGER
))
779 fprintf(stderr
, _("%s: limiting reads to AG 0\n"),
786 error
= libxfs_initialize_perag(mp
, sbp
->sb_agcount
, &mp
->m_maxagi
);
788 fprintf(stderr
, _("%s: perag init failed\n"),
797 libxfs_rtmount_destroy(xfs_mount_t
*mp
)
800 libxfs_irele(mp
->m_rsumip
);
802 libxfs_irele(mp
->m_rbmip
);
803 mp
->m_rsumip
= mp
->m_rbmip
= NULL
;
807 * Release any resource obtained during a mount.
810 libxfs_umount(xfs_mount_t
*mp
)
812 struct xfs_perag
*pag
;
815 libxfs_rtmount_destroy(mp
);
816 libxfs_bcache_purge();
818 for (agno
= 0; agno
< mp
->m_maxagi
; agno
++) {
819 pag
= radix_tree_delete(&mp
->m_perag_tree
, agno
);
823 kmem_free(mp
->m_attr_geo
);
824 kmem_free(mp
->m_dir_geo
);
826 kmem_free(mp
->m_rtdev_targp
);
827 if (mp
->m_logdev_targp
!= mp
->m_ddev_targp
)
828 kmem_free(mp
->m_logdev_targp
);
829 kmem_free(mp
->m_ddev_targp
);
834 * Release any global resources used by libxfs.
838 struct libxfs_xinit
*li
)
842 libxfs_close_devices(li
);
844 /* Free everything from the buffer cache before freeing buffer zone */
845 libxfs_bcache_purge();
846 libxfs_bcache_free();
847 cache_destroy(libxfs_bcache
);
848 leaked
= destroy_zones();
849 if (getenv("LIBXFS_LEAK_CHECK") && leaked
)
854 libxfs_device_alignment(void)
856 return platform_align_blockdev();
860 libxfs_report(FILE *fp
)
865 cache_report(fp
, "libxfs_bcache", libxfs_bcache
);
868 c
= asctime(localtime(&t
));
869 fprintf(fp
, "%s", c
);